이 'at'명령이 표준 출력으로 인쇄되지 않는 이유는 무엇입니까?


15

나는 상대적인 리눅스 초보자입니다. 사용 at하지 않고 나중에 시작하도록 작업을 예약 할 수 있도록 사용 방법을 배우려고합니다 sleep. 내가보고 된 이 이전 질문 도움.

내 질문은 내가 만든 다음 샘플 bash 스크립트에서 "실행 중" 이 표준 출력 (예 : 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호출하면 본질적으로 동일한 결과를 얻을 수 있습니다.


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

메일 대기열의 "받은 편지함"에 다음이 있습니다.

     mutt의받은 편지함의 ss

이 이메일을 확인해 봅시다 :

     mutt의 메시지의 SS

그리고 효과가있었습니다.


@ MichaelKjörling-mutt rulz 8-)
slm

5

Debian 8.1 (jessie)을 실행하고
있습니다. tty를 사용하여 'at'출력을 터미널로 보낼 수 있습니다.

$ tty
/dev/pts/1

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

1 분 후 터미널에 'ZZZZZ'가 나타납니다.


2

위의 답변은 표준 / "올바른"방법입니다.

보다 "최종 사용자"관점에서 더 간단한 또 ​​다른 방법은 예약 된 작업이나 백그라운드 작업이 출력을 "로그"파일에 쓰도록하는 것입니다. 파일은 시스템의 어느 위치 에나있을 수 있지만 작업이 루트로 실행되는 경우 ( cron등), 그 아래 /var/log에있는 파일이 있으면 좋습니다.

내가 생성 된 /var/log/maint디렉토리를하고 모두가 읽을 나는 내 백업 스크립트의 출력을 기록하는 소위 "백업"에서 읽을 수있는 파일이했다.

파일이 시스템에서 생성 된 것과 섞이지 않도록 내 디렉토리를 만들었습니다.

bash에 물건을 넣으려면 :

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

이렇게 >>하면 매번 메시지를 덮어 쓰지 않고 파일에 메시지가 추가됩니다.

내 스크립트에 많은 출력이 있으면 출력에 스크립트 또는 함수를 사용하므로 모든 것이 동일하게 수행됩니다. 아래는 내 현재 (과도한 버전)입니다.

#!/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 명령을 사용하여 로그 파일에 출력을 작성하는 예제를 제공 할 수 있습니까? 다음 방법으로 시도하고 있지만 결과는 없습니다.> echo ""hello ">> / home / camsarch / cams_scripts / texsttest. txt at> <EOT>
Pavan Kumar Varma

@PavanKumarVarma- at파일에 쓰는 데 사용하는 간단한 (테스트 된) 예제를 추가했습니다 . 예제에서 호출 시퀀스를 거꾸로 한 것 같습니다. 나는 at언제 작업을 수행 해야하는지 잘 모르기 때문에 가까운 시일 내에 시간을 하드 코딩했습니다.
Joe
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.