Dlaczego to polecenie „at” nie jest drukowane na standardowe wyjście?

15

Jestem względnym nowicjuszem na Linuksie. Staram się nauczyć, jak używać, ataby móc zaplanować rozpoczęcie zadań w późniejszym czasie, bez użycia sleep. Szukałem pomocy w poprzednim pytaniu .

Moje pytanie brzmi: w poniższym przykładowym skrypcie bash, który utworzyłem, dlaczego „Uruchamianie” nigdy nie jest - o ile wiem - wypisywane na standardowe wyjście (tj. Na moją konsolę bash)?

#!/bin/bash

echo "Started"

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

echo "Finished"

Jedyne wyjście, jakie widzę, to na przykład:

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

Czy odpowiedź na moje pytanie znajduje się w ostrzeżeniu? Jeśli tak, to czym /bin/shróżni się od standardowego wyjścia?

Andrzej
źródło
spróbuj tego:sleep 3m; echo Running
Jasen

Odpowiedzi:

18

Ponieważ atnie wykonuje poleceń w kontekście zalogowanej sesji użytkownika. Chodzi o to, że można zaplanować uruchomienie polecenia w dowolnym czasie, a następnie wylogować się, a system zajmie się uruchomieniem polecenia o określonej godzinie.

Zauważ, że strona podręcznika dla at(1)konkretnie mówi (mój nacisk):

Użytkownik otrzyma standardowy błąd i standardowe wyjście z jego poleceń, jeśli takie istnieją. Poczta zostanie wysłana za pomocą polecenia / usr / sbin / sendmail.

Dlatego powinieneś sprawdzać lokalny bufor poczty lub, w przypadku braku tego, dzienniki systemu lokalnego. / var / spool / mail / $ USER jest prawdopodobnie dobrym miejscem do rozpoczęcia.

Zauważ też, że „Rozpoczęty” i „Zakończony” pochodzą z zewnętrznego skryptu i same w sobie nie mają z tym nic wspólnego at. Możesz je usunąć lub atwywołać, a uzyskasz zasadniczo ten sam wynik.

CVn
źródło
8

Jak wyjaśnił @ MichaelKjörling, wszelkie dane wyjściowe powstałe w wyniku atpracy zostaną przechwycone i wysłane do Ciebie pocztą e-mail. Jeśli nie masz na swoim komputerze uruchomionego agenta MTA - Mail Transfer Agent, wiadomość e-mail może znajdować się w stanie zawieszenia i nie będziesz wiedział, że atnawet próbuje to zrobić.

MTA, to program, takich jak sendmaillub postfixże może „dostarczyć” e-mail do odpowiedniego przeznaczenia. W takim przypadku dostarczy go do kolejki pocztowej (pliku w katalogu /var/spool/mail) w systemie lokalnym. Każdy użytkownik w systemie może mieć kolejkę w tym katalogu.

W moim systemie Fedora, jeśli się uruchomię, sendmailmoże nastąpić lokalna dostawa poczty. Zazwyczaj jednak mam to wyłączone.

$ sudo service start sendmail

Teraz widzimy, że moja kolejka poczty dla mojego konta użytkownika samljest pusta:

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

Więc teraz wykonujemy atzadanie:

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

Widzimy, że zadanie czeka na wykonanie z atq:

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

Po ponownym uruchomieniu po kilku minutach możemy zobaczyć, że atzadanie zostało ukończone:

$ atq
$

Nawiasem mówiąc, po uruchomieniu MTA otrzymuję teraz ten komunikat w moim terminalu:

Masz nową pocztę w / var / spool / mail / saml

Sprawdźmy więc:

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

Tak, mamy pocztę, więc sprawdźmy to za pomocą mutt:

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

Mamy to w „skrzynce odbiorczej” naszej kolejki pocztowej:

     ss skrzynki odbiorczej mutta

Sprawdźmy ten e-mail:

     ss of mutt's msg

I zadziałało.

slm
źródło
@ MichaelKjörling - mutt rulz 8-)
slm
5

Używam Debiana 8.1 (jessie)
Możesz mieć wyjście „at” skierowane do terminala za pomocą 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>

Minutę później w terminalu pojawi się komunikat „ZZZZZ” ...

AAAfarmclub
źródło
2

Powyższe odpowiedzi są standardowym / „właściwym” sposobem na zrobienie tego.

Innym podejściem, które jest prostsze z punktu widzenia „użytkownika końcowego”, jest zapisanie wyników dowolnego zadania zaplanowanego lub zadania w tle w pliku „dziennika”. Plik może znajdować się w dowolnym miejscu w systemie, ale jeśli zadanie działa jako root (z cronitp.), To gdzieś poniżej /var/logjest dobre miejsce, aby go umieścić.

Utworzyłem /var/log/maintkatalog i sprawiłem, że jest czytelny dla wszystkich, a pod tym plikiem o nazwie „kopia zapasowa” mam czytelny plik, w którym loguję dane wyjściowe z moich skryptów kopii zapasowej.

Stworzyłem własny katalog, aby moje pliki nie mieszały się z elementami generowanymi przez system.

Aby umieścić tam rzeczy (w bash):

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

>>Powoduje komunikaty mają być dołączone do pliku zamiast zastępowanie go za każdym razem.

Jeśli mój skrypt ma dużo danych wyjściowych, używam skryptu lub funkcji dla danych wyjściowych, więc wszystko robi się tak samo. Poniżej moja obecna (wersja z nadmiarem umiejętności): (VERBOSE jest dostępne, gdy uruchamiam skrypt z terminala i chcę zobaczyć, co się dzieje w celu debugowania).

#!/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

Edycja: Prosty atprzykład, który zapisuje do pliku użytkownika

Nie używałem tego od zawsze, więc wymyśliłem to za pomocą kilku prostych skryptów.

Pierwszy skrypt po prostu planuje użycie zdarzenia at. Samą komendę można po prostu wpisać w terminal, ale jestem leniwy - szczególnie, gdy muszę to zrobić wiele razy podczas testowania, bez oszukiwania w historii komend.

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

Drugi skrypt jest tym, który ma zostać uruchomiony

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

Utworzyłem oba skrypty w edytorze tekstów, zapisałem je, a następnie sprawiłem, że każdy z nich jest wykonywalny chmod 700 script-file-name. $HOME/binDla wygody umieściłem je oba w moim katalogu, ale mogą być w dowolnym miejscu, w którym mój użytkownik ma pełny dostęp. Używam 700do każdego skryptu, który jest tylko do testowania, ale równie dobrze może być w systemie dla jednego użytkownika 755.

Mam już katalog, w którym /home/bigbird/logmożna zapisać dane wyjściowe mytest_at_script. Może to być także wszędzie tam, gdzie użytkownik ma pełny dostęp. Po prostu upewnij się, że istnieje przed uruchomieniem skryptu lub niech skrypt go utworzy.

Aby go uruchomić, po prostu upewniłem się, że czas na atpolecenie mytest_at_runjest trochę w przyszłości, a następnie uruchomiłem go z terminala. Potem zaczekałem, aż się uruchomi, i sprawdziłem zawartość $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$

Kilka uwag:

Mimo że uruchamiam się atod mojego użytkownika, nie zna on mojego środowiska, takiego jak mój PATHi mój katalog domowy, więc nie zakładam tego. Używam pełnych ścieżek, jak w przypadku każdej cronpracy. A jeśli kiedykolwiek będę chciał zrobić z tego cronpracę, nie będę musiał niczego zmieniać, żeby ją uruchomić.

Kiedyś >>w mytest_at_scriptcelu wyjścia dołączone do pliku dziennika zamiast >które zastąpiły go na każdym biegu. Używaj tych, które najlepiej pasują do Twojej aplikacji.

Joe
źródło
czy możesz podać mi dowolny przykład zapisu danych wyjściowych do pliku dziennika za pomocą polecenia AT, próbuję w następujący sposób, ale bez rezultatu, w tej chwili + 1 min w> echo "" hello ">> / home / camsarch / cams_scripts / texsttest. txt o> <EOT>
Pavan Kumar Varma
@PavanKumarVarma - dodano uproszczony (przetestowany) przykład przy użyciu atzapisu do pliku. Wygląda na to, że sekwencja wywołań została odwrócona w twoim przykładzie. Nie jestem zbyt dobry w mówieniu, atkiedy mam rozpocząć pracę, więc po prostu ustaliłem czas w najbliższej przyszłości.
Joe