gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 13:55:32 25 4
gpt4 key购买 nike

下面是一个脚本,该脚本登录到远程主机(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运行时,输出仅为空白。因此,在与Cacti服务器的SSH session 中,输出为:
$ ./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,脚本运行良好。因此,这似乎特定于它作为cronjob的运行,SSH命令的输出被神奇地重定向到某个地方,我不知道在哪里或为什么。

为了尝试调试它,我在脚本中添加了以下几行(直接在 #!/bin/bash下),并等待Cacti 5分钟轮询间隔运行(我每5分钟调用一次脚本就可以在Cacti日志中看到);
exec >/tmp/stdout.log 2>/tmp/stderr.log
set -x
stdout.log仅包含与 ucastv4_used:相同的 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_UCASTV4_USED变量也为空。 stdout.log最终与以前相同: ucastv4_used:
我还尝试将 #!/bin/bash更改为 #!/bin/bash -i以强制进行交互式 session 。如果我将 -i添加到脚本(可以在 echo $PS1文件中看到设置了 stdout.log的脚本中),并且没有 $PS1,则该脚本不会打印任何内容,因此可以使用 -i。但是,SSH命令仍然没有输出。 SSH输出的命令在哪里?

我也尝试过使用 ssh ..... | tee /tmp/output,以便输出应显示在 /tmp/output/tmp/stdout.log中,但两者均为空白。

我可以在远程路由器上看到SSH session 即将进入并运行命令。这是从 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服务器的交互式 session 进行的,因此我猜问题出在那里,而不是路由器。我也相信Cacti本身不是问题,我可以触发spine从我的交互式SSH session 中轮询此路由器主机,并且脚本可以正常工作(进一步指出了问题,即在非交互式shell中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

因此,似乎SSH输出正在重定向到某个地方,我无法“获取它”,或者路由器以某种方式知道这是一个非交互式SSH客户端,并且没有发回任何东西。我还能如何调试呢?

更新1
当我通过与Cacti服务器的交互式SSH session 运行脚本以及通过Cacti的轮询间隔/定时作业运行脚本时,使用Cisco路由器上的 debug ssh server捕获了调试日志。我已经将 diff输出,并且可以找到的唯一有趣的外观差异(除了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服务器的交互式 session 。我注意到在最前面的 sshd_ptytonet - Channel 1 Received EOT (bytes:1)中,而通过cronjob调试显示了 sshd_nettopty: EOF received. Disconnecting session。非交互式 session 是否只是将我的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/zero 2>/dev/null)

    关于bash - 远程主机(通过Cron的SSH)上捕获的命令输出为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44116461/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com