从 cron bash 脚本运行时 ssh 无法执行远程命令 - 从 CLI 运行

从 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 运行,并比较输出。以下是 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

任何想法大大赞赏。

答案1

尝试添加-t -t到您的 SSH 连接选项。这将强制分配一个伪终端。

多个-t选项强制分配 tty,即使ssh没有本地 tty。

答案2

您应该进一步调试脚本。请尝试以下两项操作:

将其写入文件,直接进行文件输出,而不是通过输出重定向。也就是说,在脚本中执行以下操作:

$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 可以写入?您是否已验证脚本在 cron 中运行时/root/path/to/last_run_output没有以某种方式进行设置?noclobber

编辑:根据 OP 的评论进一步提出故障排除想法。

因此,上述想法似乎都行不通。将文件列表保存在远程计算机上的文件中,然后将其 scp 回来怎么样?这将消除任何奇怪的引用或输入重定向问题。

相关内容