Linux

從 cron bash 腳本執行時 ssh 無法執行遠端命令 - 從 CLI 工作

  • October 4, 2015

我有一個用 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&lt;=0 rfd 4 len 0
-debug2: channel 0: read failed
-debug2: channel 0: close_read
-debug2: channel 0: input open -&gt; drain
-debug2: channel 0: ibuf empty
-debug2: channel 0: send eof
-debug2: channel 0: input drain -&gt; 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 -&gt; drain
debug2: channel 0: obuf empty
debug2: channel 0: close_write
debug2: channel 0: output drain -&gt; 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 -&gt; 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" &gt; savefile

在 cron 中使用 bash -x 執行腳本並保存結果。將腳本的第一行更改為#!/bin/bash -x並嘗試類似

34 * * * * /root/path/to/my/script/get_logs.sh &gt; script_debug 2&gt;&1

這應該可以幫助您準確縮小腳本正在做什麼。我懷疑在這種情況下,cron 中的輸出重定向無法正常工作。

另外,愚蠢的問題:您是否驗證過 root 可以寫入/root/path/to/last_run_outputnoclobber當腳本在 cron 中執行時,您是否驗證過您沒有以某種方式設置?

編輯:根據 OP 的評論進一步排除故障的想法。

所以上述想法似乎都沒有奏效。將 fielist 保存在遠端機器上的文件中並通過 scp 將其返回呢?這將消除任何奇怪的引用或輸入重定向問題。

引用自:https://serverfault.com/questions/224307