この「at」コマンドが標準出力として印刷されないのはなぜですか?

この「at」コマンドが標準出力として印刷されないのはなぜですか?

私はLinuxにとって比較的初心者です。atを使用せずに後で作業を開始するようにスケジュールできるように使用方法を学びたいsleep前の質問助けを求める。

私の質問は私が作った次の例のbashスクリプトでなぜ「走る」私が知っている限り、stdout(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標準出力とどう違いますか?

答え1

atこれは、ログインしたユーザーセッションのコンテキストではコマンドが実行されないためです。アイデアは、いつでもコマンドを実行するようにスケジュールし、ログアウトすると、システムが指定された時間にコマンドの実行を処理することです。

マニュアルページには次のように具体的at(1)に明示されています(私の強調)。

ユーザーにメールが送信されます。コマンドの標準エラーと標準出力(使用可能な場合)のメールは、/usr/sbin/sendmailコマンドを使用して送信されます。

したがって、ローカルメールプールを確認し、失敗した場合はローカルシステムメールログを確認する必要があります。 /var/spool/mail/$USERは始めるのに最適な場所かもしれません。

atさらに、「開始」と「完了」は外部スクリプトから派生し、それ自体はまったく関係がありません。取り出したりat電話したりすると、本質的に同じ結果が得られます。

答え2

私は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>

しばらくすると、端末に「ZZZZZ」が表示されます。

答え3

@MichaelKjörlingが説明するように、あなたの仕事で作成されたすべての結果はatキャプチャされ、あなたに電子メールで送信されます。走っていない場合MTA - メール転送エージェントat電子メールがメールボックスに表示されると、電子メールが輻輳して電子メールがこの操作を試みているという事実さえ知らない可能性があります。

sendmailMTAは、または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

このメールを見てみましょう。

     たわごとのSSメッセージ

効果がありました。

答え4

上記の答えは標準/「正しい」方法です。

より「エンドユーザー」の観点から見ると、もう1つの簡単なアプローチは、スケジュールされたジョブまたはバックグラウンドジョブがその出力を「ログ」ファイルに書き込むことです。このファイルはシステムのどこにでも配置できますが、ジョブがルート(スレーブなど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

2番目のスクリプトは、実行するようにスケジュールされたスクリプトです。

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

テキストエディタで2つのスクリプトを作成して保存し、使用しました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>

関連情報