Bash помещает вашу программу в собственную группу процессов как часть обработки управления заданиями. Например, из справочной страницы bash:
To facilitate the implementation of the user interface to job control, the operating system maintains the notion of a current terminal process group ID. Members of this process group (processes whose process group ID is equal to the current terminal process group ID) receive keyboard-generated signals such as SIG‐ INT. These processes are said to be in the foreground. Background processes are those whose process group ID differs from the terminal's; such processes are immune to keyboard-generated signals. Only foreground processes are allowed to read from or, if the user so specifies with stty tostop, write to the terminal. Background processes which attempt to read from (write to when stty tostop is in effect) the terminal are sent a SIGTTIN (SIGTTOU) signal by the kernel's terminal driver, which, unless caught, suspends the process.
Также часть оset -m
:
Monitor mode. Job control is enabled. This option is on by default for interactive shells on systems that support it (see JOB CONTROL above). All processes run in a separate process group. When a background job completes, the shell prints a line containing its exit status.
Итак, если вы хотите получить ожидаемое поведение, вы можете:
fork
внутри своего кода, чтобы создать процесс без bash. set +m
для отключения режима монитора в bash. Однако это сломает такие вещи, как fg
. Первоначально я получил ту же ошибку, что и ОП.
Изучив этот вопрос еще немного, я обнаружил, что скрипт работает нормально после определения PATH, чтобы он мог найти mtr
и mtr-packet
.
Я проверил это на:CentOS Linux release 8.2.2004 (Core)
Похоже, что cron использует другой PATH:
[root@graylog ~]# crontab -l |grep PATH
* * * * * /bin/echo $PATH >> /var/log/cron.log
[root@graylog ~]# tail -n1 /var/log/cron.log
/usr/bin:/bin
Это можно обойти, определив новый путь в скрипте. Вот посмотрите на скрипт, который находится по адресу/etc/mtr-background.sh
:
#!/bin/bash
export PATH="$PATH:/usr/sbin/"
DIR=/var/log/traces/$(/usr/bin/date +%Y-%m-%d)/$(/usr/bin/date +"%H")/
DIR_FILE=$DIR$(/usr/bin/date +"%M")
mkdir -p $DIR
/usr/sbin/mtr -o "L SRD NBAW JMXI" -w -e -c 60 -4 1.1.1.1 >> $DIR_FILE
Вот относительная запись в crontab, которая была настроена под учетной записью пользователя root:
* * * * * /etc/mtr-background.sh >> /var/log/cron.log
Я нашел полный PATH для mtr
и mtr-packet
, используя whereis
вот так:
[root@graylog ~]# whereis mtr; whereis mtr-packet
mtr: /usr/sbin/mtr /usr/share/man/man8/mtr.8.gz
mtr-packet: /usr/sbin/mtr-packet /usr/share/man/man8/mtr-packet.8.gz
Спасибо