捕获的远程主机上的命令输出(SSH通过Cron)为空

时间:2017-05-22 15:11:25

标签: bash ssh io-redirection cacti

下面是一个登录远程主机(Cisco IOS-XR路由器)并通过SSH运行单个命令的脚本。我们的想法是获取命令的结果(一个整数),以便Cacti可以绘制它。当Cacti运行它的正常轮询程序时,它每5分钟运行一次这个脚本:

#!/bin/bash

if [[ -z $1 ]]
then
    exit 1
fi

HOST="$1"
USER="cact-ssh-user"
TIMEOUT=10s
export SSHPASS="aaaaaaaaaaaaa"

CMD="show controllers np struct IPV4-LEAF-FAST-P np0 | in Entries"
RAW_OUTPUT=$(timeout $TIMEOUT sshpass -e ssh -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null $USER@$HOST "$CMD" 2>/dev/null)
GRT_UCASTV4_USED=$(echo -n "$RAW_OUTPUT" | grep "Entries" | awk '{print $6}' | tr -d "," | tr -d " ")

echo -n "ucastv4_used:$GRT_UCASTV4_USED"

此命令通过交互式shell工作正常(当我使用/path/to/script/script.sh 10.0.0.1在Cacti服务器上运行脚本时。但是当Cacti cronjob运行时,输出只是空白。所以在我与SSH服务器的SSH会话中输出是:

$ ./script 10.0.0.1
ucastv4_used:1234

在Cacti日志中,输出为:05/22/2017 03:35:21 PM - SPINE: Poller[0] Host[69] TH[1] DS[6837] SCRIPT: /opt/scripts/cacti-scripts/asr9001-get-tcam-ucast-usage.sh 10.0.0.1, output: ucastv4_used:

我有su给Cacti用户,脚本运行正常。所以这似乎特定于它作为一个cronjob运行,来自SSH命令的输出被神奇地重定向到某个地方,我不知道在哪里或为什么。

为了尝试调试这个,我在脚本中添加了以下行(直接在#!/bin/bash下)并等待Cacti 5分钟轮询间隔运行(我可以在调用脚本时在Cacti日志中看到每5分钟一次;

exec >/tmp/stdout.log 2>/tmp/stderr.log
set -x

stdout.log只包含与ucastv4_used:相同的cacti.logstderr.log文件包含远程SSH主机的登录横幅,而不包含任何其他内容。 SSH输出在哪里消失了?

我已经厌倦了更改脚本中的SSH行以输出到文件,然后从那里读取:

timeout $TIMEOUT sshpass -e ssh -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null $USER@$HOST "$CMD" > /tmp/output 2>/dev/null
GRT_UCASTV4_USED=$(grep "Entries" /tmp/output | awk '{print $6}' | tr -d "," | tr -d " ")

文件/tmp/output为空,因此GRT_UCASTV4_USED变量也为空。 stdout.log最终与之前相同:ucastv4_used:

我还尝试将#!/bin/bash更改为#!/bin/bash -i以强制进行互动会话。如果我在-i文件中添加echo $PS1stdout.log设置了$PS1并且没有-i,那么ssh ..... | tee /tmp/output就可以使用/tmp/output。没有打印。但是,SSH命令仍然没有输出。 SSH输出的命令在哪里?

我还尝试使用/tmp/stdout.log,以便输出显示在debug ssh serverRP/0/RSP0/CPU0:May 22 14:52:57.976 UTC: SSHD_[65909]: (open_master_file) command added show controllers np struct IPV4-LEAF-FAST-P np0 | in Entries 中,但两者都是空白的。

我可以在远程路由器上看到SSH会话正在进入并运行该命令。这来自$ cd /usr/local/spine/bin $ ./spine -V 7 69 69 ... 05/22/2017 04:06:56 PM - SPINE: Poller[0] Host[69] TH[1] DS[6837] SCRIPT: /opt/scripts/cacti-scripts/asr9001-get-tcam-ucast-usage.sh 10.0.0.1, output: ucastv4_used:658809

debug ssh server

此外,由于这是通过我与Cacti服务器的交互式会话工作,我猜测问题就在那里,而不是路由器。我也相信Cacti它的自我不是问题,我可以触发脊椎从我的交互式SSH会话轮询这个路由器主机并且脚本工作正常(进一步指出一些非交互式的问题) shell的输出是蒸发):

diff

所以似乎SSH输出被重定向到某个地方我无法得到它"或路由器以某种方式知道这是一个非交互式SSH客户端,并且不会发回任何东西。我还能怎么调试呢?

更新1 在Cisco路由器上使用*** 132,145 **** (sshd_interactive_shell) *** removing alarm sshd_interactive_shell - ptyfd = 46 event_contex_init done ! sshd_ptytonet - Channel 1 Received EOT (bytes:1) ! sshd_ptytonet - Channel 1 exec command executed sending CHANNEL_CLOSE ! (close_channel), pid:182260085, sig rcvd:1, state:10 chan_id:1 ! addrem_ssh_info_tuple: REMOVE Inside the critical Section %pid:182260085 ! Cleanup sshd process 182260085, session id 1, channel_id 1 ! addrem_ssh_info_tuple: REMOVE exiting the Critical Section %pid:182260085 close_channel: Accounting stopped: scriptaccount ! In delete channel code, pid:182260085, sig rcvd:1, state:10 chan_id:1 Sending Exit Status: 0 sig: 1 Sending Channel EOF msg Sending Channel close msg for remote_chan_id = 0 chan_id = 1 --- 134,147 ---- (sshd_interactive_shell) *** removing alarm sshd_interactive_shell - ptyfd = 46 event_contex_init done ! Pad_len = 6, Packlen = 12 ! sshd_nettopty: EOF received. Disconnecting session ! (close_channel), pid:182329717, sig rcvd:1, state:10 chan_id:1 ! addrem_ssh_info_tuple: REMOVE Inside the critical Section %pid:182329717 ! Cleanup sshd process 182329717, session id 1, channel_id 1 ! addrem_ssh_info_tuple: REMOVE exiting the Critical Section %pid:182329717 close_channel: Accounting stopped: scriptaccount ! In delete channel code, pid:182329717, sig rcvd:1, state:10 chan_id:1 Sending Exit Status: 0 sig: 1 Sending Channel EOF msg Sending Channel close msg for remote_chan_id = 0 chan_id = 1 我通过交互式SSH会话运行脚本到Cacti服务器时以及通过Cacti的轮询间隔/ cron作业运行时捕获了调试日志。我有sshd_ptytonet - Channel 1 Received EOT (bytes:1)输出的输出和我能找到的唯一有趣的外观差异(除了像改变的MSC PID更改和Cacti服务器的临时源端口之类的东西之外)如下:

sshd_nettopty: EOF received. Disconnecting session

上半部分是我与Cacti服务器的交互式会话。我在顶部的{{1}}注意到,而通过cronjob,调试显示{{1}}。非交互式会话是否只是将SSH命令传递给远程主机并尽快退出(因此它不等待SSH服务器使用命令输出进行响应)?

1 个答案:

答案 0 :(得分:2)

  • 首先,告诉SSH客户端不要使用-T选项分配PTY,因为显然cron没有。
  • 然后在stdin上给它一些无限的东西,所以它会继续运行直到stdout 是开放的,我们/ dev / zero完全是为了这个目的。

RAW_OUTPUT=$(timeout $TIMEOUT sshpass -e ssh -T -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null $USER@$HOST "$CMD" </dev/zero 2>/dev/null)