從 cron bash 腳本執行時 ssh 無法執行遠端命令 - 從 CLI 工作
我有一個用 bash 編寫的腳本,它從 cron 執行。它所做的第一件事就是通過 SSH 連接到遠端主機並檢索目錄中的文件列表。從命令行執行時一切正常,但不能從 cron 執行。
腳本的部分最初如下所示:
FILES=$($SSH_BINARY -i $SSH_KEY $SSH_USER@$REMOTE_HOST "ls $REMOTE_DIRECTORY") echo "Got files = $FILES"
我在該行上方添加了一個 echo 語句(如下所示),以證明它不是路徑或變數問題:
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 中使用調試標誌。我從命令行執行一次,然後從 cron 執行,並比較了輸出。以下是差異的一些亮點:
- 側是不成功的嘗試,+ 側是成功的嘗試,執行在 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
任何想法都非常感謝。
嘗試添加
-t -t
到您的 SSH 連接選項。這會; 強制分配一個偽終端。多個
-t
選項強制 tty 分配,即使ssh
沒有本地 tty。
您應該進一步調試您的腳本。有兩件事要嘗試:
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
?noclobber
當腳本在 cron 中執行時,您是否驗證過您沒有以某種方式設置?編輯:根據 OP 的評論進一步排除故障的想法。
所以上述想法似乎都沒有奏效。將 fielist 保存在遠端機器上的文件中並通過 scp 將其返回呢?這將消除任何奇怪的引用或輸入重定向問題。