Cronから実行されるbashで記述されたスクリプトがあります。最初に行うことの1つは、リモートホストにSSHで接続し、ディレクトリ内のファイルのリストを取得することです。コマンドラインから実行するとすべてが正常に動作しますが、cronからは動作しません。
スクリプトのセクションは元々次のようになりました。
FILES=$($SSH_BINARY -i $SSH_KEY $SSH_USER@$REMOTE_Host "ls $REMOTE_DIRECTORY")
echo "Got files = $FILES"
パスや変数の問題ではないことを証明するために、その行の上にエコーステートメントを追加しました(以下を参照)。
echo "$SSH_BINARY -i $SSH_KEY $SSH_USER@$REMOTE_Host \"ls $REMOTE_DIRECTORY\""
結果の出力行を取得して、同じユーザーcronが(root)として実行すると、問題なく機能します。
変数への割り当てと関係があるのではないかと思って、FILES =行を読み取るように変更しました(したがって、出力を直接last_run_outputファイルに入れます)。
$SSH_BINARY -vv -i $SSH_KEY $SSH_USER@$REMOTE_Host "ls $REMOTE_DIRECTORY"
Cronエントリは次のようになります。
34 * * * * /root/path/to/my/script/get_logs.sh > /root/path/to/last_run_output 2>&1
そのため、PATH、変数の割り当て、およびアクセス許可の問題はさておき、sshでデバッグフラグを使用し始めました。コマンドラインから1回実行し、次にcronから実行して、出力を比較しました。以下は、diffのハイライトです。
-側は失敗した試行であり、+側は成功した試行であり、cronの外部で実行されます。
@@ -87,9 +77,7 @@
debug1: Remote: X11 forwarding disabled.
debug1: Remote: Forced command: /home/sshacs/acssshsink netstorageuser
debug1: Authentication succeeded (publickey).
-debug2: fd 4 setting O_NONBLOCK
debug2: fd 5 setting O_NONBLOCK
-debug2: fd 6 setting O_NONBLOCK
debug1: channel 0: new [client-session]
debug2: channel 0: send open
debug1: Entering interactive session.
これらの余分なファイル記述子がcronから実行されたときにdebug2で言及される理由を説明することはできませんが、関連しているようです(以下のread <= 0 rfd 4 len 0行に注意してください)。
@@ -100,20 +88,672 @@
debug2: callback done
debug2: channel 0: open confirm rwindow 0 rmax 32768
debug2: channel 0: rcvd adjust 131072
-debug2: channel 0: read<=0 rfd 4 len 0
-debug2: channel 0: read failed
-debug2: channel 0: close_read
-debug2: channel 0: input open -> drain
-debug2: channel 0: ibuf empty
-debug2: channel 0: send eof
-debug2: channel 0: input drain -> closed
+ [[ Very large output of the ls command ]]
+debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug2: channel 0: rcvd eof
debug2: channel 0: output open -> drain
debug2: channel 0: obuf empty
debug2: channel 0: close_write
debug2: channel 0: output drain -> closed
-debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug2: channel 0: rcvd close
+debug2: channel 0: close_read
+debug2: channel 0: input open -> closed
debug2: channel 0: almost dead
debug2: channel 0: gc: notify user
debug2: channel 0: gc: user detached
どんなアイデアでもとても高く評価されています。
SSH接続オプションに-t -t
を追加してみてください。この意志;疑似端末を強制的に割り当てます。
複数の
-t
オプションは、ssh
にローカルttyがない場合でも、ttyの割り当てを強制します。
スクリプトをさらにデバッグする必要があります。試す2つのこと:
出力リダイレクトを介さずに直接ファイル出力を行うようにRwriteします。つまり、スクリプトで次のようにします。
$SSH_BINARY -i $SSH_KEY $SSH_USER@$REMOTE_Host "ls $REMOTE_DIRECTORY" > savefile
Cron内でbash-xを使用してスクリプトを実行し、結果を保存します。スクリプトの最初の行を#!/bin/bash -x
に変更して、次のように試してください
34 * * * * /root/path/to/my/script/get_logs.sh > script_debug 2>&1
これにより、スクリプトの実行内容を正確に絞り込むことができます。この場合、cronでの出力のリダイレクトが正しく機能していないと思われます。
また、ばかげた質問:rootが/root/path/to/last_run_output
に書き込むことができることを確認しましたか?スクリプトがcronで実行されているときにnoclobber
が設定されていないことを確認しましたか?
編集:OPからのコメントに基づいたさらなるトラブルシューティングのアイデア。
したがって、上記のアイデアはどれも機能していないようです。フィーリストをリモートマシン上のファイルに保存して、元に戻すのはどうですか?これにより、奇妙な引用や入力リダイレクトの問題が解消されます。