Чому ця команда "at" не друкується на стандартний вихід?


15

Я родич Linux. Я намагаюся навчитися користуватися, atщоб я міг запланувати завдання, щоб почати їх пізніше, без використання sleep. Я розглядав це попереднє запитання про допомогу.

Моє запитання в наступному зразковому скрипті 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
Ясен

Відповіді:


18

Тому atщо не виконує команди в контексті Вашого входу в систему. Ідея полягає в тому, що ви можете запланувати команду для запуску в довільний час, після чого вийдете з системи, і система подбає про виконання команди в зазначений час.

Зауважте, що на сторінці керівництва at(1)конкретно сказано (мій акцент):

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

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

Також зауважте, що "Початок" та "Готово" походять із зовнішнього сценарію і самі по собі взагалі не мають нічого спільного at. Ви можете вийняти їх або atвиклик, і ви отримаєте по суті такий же результат.


8

Як @ MichaelKjörling пояснив, що будь-який результат, отриманий вашою atроботою, буде захоплений та надісланий вам електронною поштою. Якщо у вас в коді не працює запуск MTA - агента передачі пошти, то повідомлення електронної пошти може перебувати в кінцівці, і ви не знаєте, що 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
$

Між іншим, під час роботи МТА я отримую це повідомлення у своєму терміналі:

У вас є нова пошта в / 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 папки вхідних повідомлень

Давайте перевіримо цей електронний лист:

     ss of mutt's msg

І це спрацювало.


@ 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» ...


2

Наведені вище відповіді - це стандартний / «правильний» спосіб зробити це.

Інший підхід, який є більш простим з точки зору "кінцевого користувача", полягає в тому, щоб будь-яке заплановане або фонове завдання записало свій вихід у файл "журналу". Файл може бути в будь-якій точці вашої системи, але якщо завдання працює як root (від cronтощо), то десь під ним /var/log- це гарне місце для його розміщення.

Я створив /var/log/maintкаталог і зробив його читабельним усіма, і у мене є читабельний файл під тим, що називається "резервна копія", де я реєструю висновки зі своїх резервних скриптів.

Я створив власний каталог, щоб мої файли не змішувалися з речами, створеними системою.

Щоб помістити речі туди (в баш):

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

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

Якщо мій сценарій має багато результатів, я використовую сценарій або функцію для виводу, щоб все було зроблено так само. Нижче наводиться моя поточна (версія overkill): (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команду в 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 at> <EOT>
Pavan Kumar Varma

@PavanKumarVarma - додав спрощений (тестований) приклад, використовуючи atдля запису у файл. Схоже, ви отримали послідовність викликів назад у своєму прикладі. Я не дуже добре розказую, atколи потрібно виконувати роботу, тому я просто важко зафіксував час у найближчому майбутньому.
Джо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.