我在使用invoke shell接收来自特定命令的输出时遇到问题。该脚本的目的是登录并检查linux / unix服务器上特定应用程序的状态。问题源于服务器列表庞大,并且并非所有服务器都具有该应用程序。因此,该脚本可在具有该应用程序的服务器上运行,甚至可以拉取数据并将其打印到屏幕上,但是当脚本出现“ -bash:CMD:未找到命令”时,该脚本将挂起,并且不会遍历列表。 / p>
我还确认使用wireshark和过滤服务器的IP ip.addr == x.x.x.x TCP连接已建立,因此排除了该路径上的任何ACL,FW和/或IP表。由于wireshark中的数据包已加密,因此我无法进一步详细说明。
我可以看到服务器与我的桌面(客户端)进行通信,并发送多个镜头的多个加密数据包。该脚本似乎挂在打印语句之前(卡住了)。
现在最理想的情况是使用exec shell,但是我希望将此脚本设计为将来可伸缩。
我以前在网络设备甚至服务上使用过此脚本,当预期的响应具有统一的含义,显示路由,uname -a时,这些脚本都可以工作,但是这些都是预期的结果,但是我认为其中有些不同到bash没有命令错误,导致接收问题。
# ***** Open Plain Text
f = open("nfsus.txt")
# ***** Read & Store into Variable
hn=(f.read().splitlines())
f.close()
# ***** Credentials
#username = raw_input("Please Enter Username: ")
#password = getpass.getpass("Please Enter Passwod: ")
# ***** SSH
client=paramiko.SSHClient()
def connect_ssh(hn):
try:
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hn, 22, username, password, look_for_keys=False, allow_agent=False)
print 'Connection Attempting to: '+(hn)
channel = client.get_transport().open_session()
channel.invoke_shell()
channel.sendall("CMD \n")
cmd = channel.recv(1024)
#SCRIPT HANGS HERE! ^
print ('stuck')
#print (cmd)
except Exception, e:
print '*** Caught exception: %s: %s' % (e.__class__, e)
try:
channel.close()
except:
pass
# *****Create Loop through input.txt (contains a list of IP address)
for x in hn:
connect_ssh(x)
我是Python新手,并且承认,我很难受!但是,我确实尽最大的努力来理解脚本的每个细节。我一生中从未用python或任何其他语言写过任何东西。我很高兴学习,但是请耐心等待,因为我很烂!我仔细阅读了paramiko文档,但是有些事情我还没有完全理解,我希望这里的人足够酷,可以向这个菜鸟展示我的方式的错误。
谢谢
答案 0 :(得分:1)
在狗狗时代,我还没有看过Paramiko,但是在这种情况下,bash(shell)在“ STDERR”而不是“ STDOUT”上发送错误消息。可能是Paramiko没有在听STEDRR,所以它没有收到错误消息,或者是以其他方式捕获它们。
ortep@Motte ~
$ foobar
-bash: foobar: command not found
ortep@Motte ~
$ foobar 2>/dev/null
ortep@Motte ~
$
在第二次调用“ foobar”时,我将(>)STDERR(2)重定向到/ dev / null设备。
您还可以将其重定向到“ STDOUT”:
ortep@Motte ~
$ foobar 2>&1
-bash: foobar: command not found
这看起来是一样的,因为在ssh控制台上,STDOUT和STDERR是(相同的)东西。
因此,这给了您两个可能有所帮助的选择。一种方法是:
channel.sendall("CMD 2>&1 \n")
另一种是检查命令是否存在:
channel.sendall("if [[-x /path/to/CMD ]]; then /path/to/CMD/; else echo "CMD not found"; fi \n)
第一个更容易尝试,第二个可以在“ else”部分扩展以提供更多信息(例如“;否则,回显“ CMD不在$(hostname)上”)。有用)。