Почему эта команда at не выводится на стандартный вывод?

15

Я относительный новичок в Linux. Я пытаюсь узнать, как использовать, atчтобы я мог запланировать задачи на более позднее время, без использования sleep. Я смотрел на этот предыдущий вопрос о помощи.

Мой вопрос в следующем примере скрипта bash, который я создал, почему «Running» никогда - насколько я могу судить - не выводится на стандартный вывод (т. Е. На мою консоль bash)?

#!/bin/bash

echo "Started"

at now + 1 minutes <<EOF
echo "Running"
EOF

echo "Finished"

Единственный вывод, который я вижу, например:

Started
warning: commands will be executed using /bin/sh
job 3 at Fri Jul 12 17:31:00 2013
Finished

Найден ли ответ на мой вопрос в предупреждении? Если так, как /bin/shотличается от стандартного вывода?

Андрей
источник
попробуйте это:sleep 3m; echo Running
Jasen

Ответы:

18

Потому atчто не выполняет команды в контексте вашей авторизованной пользовательской сессии. Идея состоит в том, что вы можете запланировать выполнение команды в произвольное время, а затем выйти из системы, и система позаботится о запуске команды в указанное время.

Обратите внимание, что страница руководства для at(1)специально говорит (мой акцент):

Пользователю будет отправлена стандартная ошибка по почте и стандартный вывод из его команд, если таковые имеются. Почта будет отправлена ​​с помощью команды / usr / sbin / sendmail.

Таким образом, вы должны проверять свою локальную почтовую катушку или, в случае неудачи, журналы локальной системы. / var / spool / mail / $ USER, вероятно, хорошее место для начала.

Также обратите внимание, что «Начатый» и «Завершенный» происходят из внешнего сценария и сами по себе не имеют ничего общего с at. Вы можете убрать их или atвызов, и вы получите по существу тот же результат.

CVn
источник
8

Как объяснил @ MichaelKjörling, любой результат, полученный вашей atработой, будет записан и отправлен вам по электронной почте. Если в вашем почтовом ящике не запущен агент MTA - Mail Transfer Agent, возможно, электронное письмо находится в подвешенном состоянии, и вы даже не узнаете, что atон пытается это сделать.

MTA - это такая программа, которая может sendmailили postfix«доставить» электронную почту в соответствующий пункт назначения. В этом случае он будет доставлен в почтовую очередь (файл в каталоге /var/spool/mail) в вашей локальной системе. Каждый пользователь в системе может иметь очередь в этом каталоге.

В моей системе Fedora, если я запускаюсь, sendmailможет происходить локальная доставка почты. У меня, как правило, есть, хотя.

$ sudo service start sendmail

Теперь мы видим, что моя почтовая очередь для моей учетной записи пользователя samlпуста:

$ ll /var/spool/mail/|grep saml
-rw-rw----. 1 saml mail       0 Jul 12 19:33 saml

Итак, теперь мы запускаем atработу:

$ at now + 1 minutes <<EOF
echo "Running"
EOF
job 96 at Fri Jul 12 19:38:00 2013

Мы можем видеть, что работа ожидает выполнения с atq:

$ atq
96  Fri Jul 12 19:38:00 2013 a saml

Запустив его снова через пару минут, мы увидим, что atработа завершена:

$ atq
$

Между прочим, с моим запущенным MTA я теперь получаю это сообщение в моем терминале:

У вас есть новая почта в / var / spool / mail / saml

Итак, давайте проверим:

$ ll /var/spool/mail/|grep saml
-rw-rw----. 1 saml mail     651 Jul 12 19:38 saml

Да, у нас есть почта, так что давайте проверим это, используя mutt:

$ mutt -f /var/spool/mail/saml

У нас есть это в "почтовом ящике" нашей почтовой очереди:

     ss из почтового ящика mutt

Давайте проверим это письмо:

     ss сообщения Mutt

И это сработало.

SLM
источник
@ MichaelKjörling - mutt rulz 8-)
slm
5

Я использую Debian 8.1 (jessie).
Вы можете получить вывод 'at' в терминал, используя tty.

$ tty
/dev/pts/1

$ at now + 1 min
warning: commands will be executed using /bin/sh
at> echo 'ZZZZZ' > /dev/pts/1
at> <EOT>

Через минуту, и ZZZZZ появится в вашем терминале ...

AAAfarmclub
источник
2

Приведенные выше ответы являются стандартным / «правильным» способом сделать это.

Другой подход, более простой с точки зрения «конечного пользователя», заключается в том, чтобы любая запланированная или фоновая задача записывала свои выходные данные в файл «журнала». Файл может находиться где угодно в вашей системе, но если задача выполняется от имени пользователя root (из cronи т. Д.), То где-то под /var/logэто хорошее место для ее размещения.

Я создал /var/log/maintкаталог и сделал его доступным для чтения всем, и у меня есть читаемый файл под названием «backup», в который я записываю выходные данные из моих скриптов резервного копирования.

Я создал свой собственный каталог, чтобы мои файлы не смешивались с вещами, сгенерированными системой.

Чтобы положить вещи там (в Bash):

BACKUP="/var/log/maint/backup"
echo "my message" >> "${BACKUP}"

>>Приводит к тому , что сообщения будут добавляться к файлу вместо перезаписи его каждый раз.

Если у моего сценария много выходных данных, я использую сценарий или функцию для вывода, поэтому все выполняется одинаково. Ниже моя текущая версия (версия с избыточным количеством ресурсов): (материал VERBOSE существует, когда я запускаю скрипт из терминала и хочу посмотреть, что происходит в целях отладки.)

#!/bin/bash
## backup_logger
## backup system logging module
## Copyleft 01/20/2013 JPmicrosystems
## Usage is ${SCRIPT_NAME} [-v] [<caller> <log message text>]
## If present, -v says log to console as well as to the log file
## <caller> is the name of the calling script
## If <caller> <log message text> is not present, write a blank line to the log

## Must be placed in path, like ~/bin
## If log is owned by root or another user, then this must run as root ...
## If not, it just aborts

##source "/home/bigbird/bin/bash_trace"  ## debug
SCRIPT_NAME="$(basename $0)"
USAGE="Usage is ${SCRIPT_NAME} [-v] [<caller> <log message text>]"
SYSLOGDIR='/var/log/maint'
SYSLOGFILE="${SYSLOGDIR}/backup.log"

LOGGING=1
VERBOSE=0
if [ "${1}" == "-v" ]
then
  VERBOSE=1
  shift
fi

##LOGGING=0  ## debug
##VERBOSE=1  ## debug

## Only zero or two parameters allowed - <caller> <log message text>
RC=0
if [ "$#" -eq 1 ] || [ "$#" -gt 2 ]
then
  echo "${USAGE}"
  RC=1
else
  if [ ! -w "${SYSLOGFILE}" ]
  then
    touch "${SYSLOGFILE}"
    if [ $? -ne 0 ]
    then
      echo -e "$(date) ${1} ${2}"
      echo "${SCRIPT_NAME} Can't write to log file [${SYSLOGFILE}]"
      RC=1
      exit ${RC}
    fi
  fi

  if [ -n "${1}" ]
  then
    (( LOGGING )) && echo -e "$(date) ${1} ${2}"  >> "${SYSLOGFILE}"
    (( VERBOSE )) && echo -e "$(date) ${1} ${2}"
  else
    (( LOGGING )) && echo "" >> "${SYSLOGFILE}"
    (( VERBOSE )) && echo ""
  fi
fi

exit $RC

Изменить: упрощенный atпример, который пишет в файл пользователя

Я не использовал это вечно, поэтому я понял это с помощью пары простых скриптов.

Первый скрипт просто планирует событие, используя at. Сама команда может быть просто набрана в терминале, но я ленив, особенно когда мне приходится делать это несколько раз во время тестирования, не дурачясь с историей команд.

#!/bin/bash
## mytest_at_run
## Schedule a script to run in the immediate future
echo "/home/bigbird/bin/mytest_at_script" | at 00:56

Второй сценарий - тот, который планируется запустить

#!/bin/bash
## mytest_at_script
## The script to be run later
echo "$(date) - is when this ran" >> /home/bigbird/log/at.log

Я создал оба сценария в текстовом редакторе, сохранил их, а затем сделал их исполняемыми chmod 700 script-file-name. Я поместил их обоих в свой $HOME/binкаталог для удобства, но они могут быть где угодно, у моего пользователя есть полный доступ. Я использую 700для любого сценария, который только для тестирования, но в однопользовательской системе, это может быть так же хорошо 755.

У меня уже есть каталог /home/bigbird/logдля сохранения выходных данных mytest_at_script. Это также может быть в любом месте, где у вашего пользователя есть полный доступ. Просто убедитесь, что он существует до запуска скрипта или создайте его.

Чтобы запустить его, я просто позаботился о том, чтобы время для atкоманды in mytest_at_runбыло немного в будущем, а затем запустил его из терминала. Затем я подождал, пока он не побежал, и осмотрел содержимое $HOME/log/at.log.

bigbird@sananda:~/bin$ cat ~/log/at.log
Fri Sep 14 00:52:18 EDT 2018 - is when this ran
Fri Sep 14 00:56:00 EDT 2018 - is when this ran
bigbird@sananda:~/bin$

Несколько заметок:

Несмотря на то, что я работаю atот своего пользователя, он не знает мою среду, такую ​​как мой PATHи мой домашний каталог, поэтому я этого не предполагаю. Я использую полные пути, как я бы для любой cronработы. И если я когда-нибудь захочу сделать это cronработой, мне не придется ничего менять, чтобы заставить это работать.

Я использовал >>в mytest_at_scriptдля вывода дописать в файл журнала вместо >который заменил бы его на каждом запуске. Используйте тот, который подходит вашему приложению лучше всего.

Джо
источник
Можете ли вы предоставить мне какой-либо пример для записи выходных данных в файл журнала с помощью команды AT, я пытаюсь следующим образом, но безрезультатно, сейчас + 1 мин при> echo "" привет ">> / home / camsarch / cams_scripts / texsttest. TXT на> <EOT>
Паван Кумар Варма
@PavanKumarVarma - добавлен упрощенный (проверенный) пример, используемый atдля записи в файл. Похоже, вы получили последовательность вызовов назад в вашем примере. Я не очень хорошо знаю, atкогда начинать работу, поэтому я просто жестко запрограммировал время в самом ближайшем будущем.
Джо