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

Bash 远程主机(通过Cron的SSH)上捕获的命令输出为空,bash,ssh,io-redirection,cacti,Bash,Ssh,Io Redirection,Cacti,下面是登录到远程主机(Cisco IOS-XR路由器)并通过SSH运行单个命令的脚本。其想法是获取命令的结果(一个整数),以便可以用仙人掌将其绘制成图形。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

下面是登录到远程主机(Cisco IOS-XR路由器)并通过SSH运行单个命令的脚本。其想法是获取命令的结果(一个整数),以便可以用仙人掌将其绘制成图形。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运行时,输出为空。因此,在与Cacti服务器的SSH会话中,输出为:

$ ./script 10.0.0.1
ucastv4_used:1234
在仙人掌日志中,输出为:
2017年05月22日03:35:21 PM-SPINE:Poller[0]主机[69]TH[1]DS[6837]脚本:/opt/scripts/Cacti scripts/asr9001-get-tcam-ucast-usage.sh 10.0.0.1,输出:ucastv4\u used:

我已经将
su
”发送给了Cacti用户,脚本运行得很好。因此,这似乎是作为cronjob运行的,SSH命令的输出被神奇地重定向到某个地方,我不知道在哪里或为什么

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

stdout.log
只包含
ucastv4\u使用:
cacti.log
相同,
stderr.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\u UCASTV4\u
变量也为空。
stdout.log
与之前相同:
UCASTV4\u使用:

我还尝试将
#!/bin/bash
更改为
#!/bin/bash-I
,以强制进行交互式会话。如果我将
echo$PS1
添加到
stdout.log
文件中可以看到
$PS1
已设置且未设置
-I
的脚本中,这种方法将不会打印任何内容。但是仍然没有SSH命令的输出。SSH输出的命令要去哪里

我还尝试使用
ssh…| tee/tmp/output
,这样输出应该显示在
/tmp/output
/tmp/stdout.log
中,但两者都是空的

我可以在远程路由器上看到SSH会话正在进入并运行该命令。这是来自
debug SSH server

RP/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
另外,由于这是通过我与Cacti服务器的交互会话工作的,我猜问题在那里,而不是路由器。我也相信Cacti本身不是问题,我可以触发spine从我的交互SSH会话轮询此路由器主机,脚本工作正常(进一步指出在非交互式shell中SSH输出如何蒸发的问题):

因此,SSH输出似乎被重定向到某个地方,我无法“获取”,或者路由器不知何故知道这是一个非交互式SSH客户端,并且没有发送任何内容。我还可以如何调试它

更新1 使用Cisco路由器上的
debug ssh server
,当我通过到Cacti服务器的交互式ssh会话运行脚本时,以及当它通过Cacti的轮询间隔/cron作业运行时,我捕获了调试日志。我已经
区分了输出和我能找到的唯一有趣的区别(除了SSH PID变更、Cacti服务器临时源端口变更等内容)如下:

*** 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
上半部分是我与Cacti服务器的交互会话。我在上半部分中注意到了sshd_ptytonet-通道1接收到的EOT(字节:1)
而通过cronjob,调试显示收到了
sshd\u netopty:EOF。断开会话的连接
。非交互式会话是否只是将我的SSH命令传递给远程主机并尽快退出(因此它不会等待SSH服务器响应命令输出)?

    首先,告诉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/null)

哇,这是一个经过适当研究的质量问题。这里,我有一个+1!我猜远程命令知道它是在“哑”模式下运行的shell,因此不输出任何内容。您可以通过显式调用远程bash来解决此问题。您尝试调用交互式shell时,最好在远程主机上尝试,而不是在本地。此外,设置shell和TERM可能会有所帮助。遗憾的是,我无法调用交互式bash(或其他)shell在远程主机上,因为它是Cisco路由器,所以在通过SSH连接时,我会被放到他们的专有CLI中。
$ 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
*** 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