通过Python子进程SSH后终端卡住了

5

我已经在进行这项工作很长时间了,任何帮助都将不胜感激。

我的目标是通过SSH连接到测试服务器,然后使用Python在该文件夹中跳转到上级目录并列出其中的所有子目录。下面是我最好的尝试代码:

def subprocess_cmd(command):
    process = subprocess.Popen(command,stdout=subprocess.PIPE, shell=True)
    print "Test 1"
    proc_stdout = process.communicate()[0].strip()
    #proc_stdout= process.stdout.readlines() (Gives same outcome as communicate)
    #proc_stdout= process.stdout.read()  (Gives same outcome as communicate)
    print "Test 2"
    print proc_stdout

subprocess_cmd('ssh user@server -p 111;cd ..;ls')

由于某些原因,这个函数总是在“proc_stdout=”步骤停顿。 它从未打印出“Test 2”或返回文件列表。 如果我删除ssh命令,它就可以正常工作。 我期望在终端中看到类似于以下内容的东西,但实际上终端会挂起,我无法再与其交互:

dredbounds-computer: python file_name.py
Test 1
Test 2
FileA
FileB
FileC

更新: 我修改了代码,并将proc_stdout = process.stderr. communicate()。这是我的更新代码:

def subprocess_cmd(command):
    process = subprocess.Popen(command,stdout=subprocess.PIPE, shell=True)
    print "Test 1"
    proc_stderr= process.stderr. communicate()
    print "Test 2"
    print proc_stderr
    print "Test 3"

运行时,我在终端中遇到了以下错误:
dredbounds-computer: python terminal_test.py
Test 1
Traceback (most recent call last):
  File "file_name.py", line 26, in <module>
    subprocess_cmd('ssh user@server -p 111;cd ..;ls')
  File "terminal_test.py", line 21, in subprocess_cmd
    proc_stdout= process.stderr. communicate()
AttributeError: 'NoneType' object has no attribute 'communicate'

有人知道我如何修复这段代码,或者用另一种方式实现相同的功能吗?不确定为什么会出现无类型错误。我调用ssh命令的方式有问题吗?我在终端手动输入了相同的命令,并返回了一个目录列表,所以理论上应该可以正常工作。有什么建议吗?


通信等待直到进程退出(如果您正在执行ssh,则可能是在键入“exit”时) - Joran Beasley
1
我尝试使用proc_stdout= process.stdout.readlines()和proc_stdout= process.stdout.read()。结果相同。 - dredbound
它可能会写入到stderrcommunicate返回一个元组,如果无法连接到服务器,则标准输出可能没有任何内容被写入。 - cdarke
谢谢,我尝试了那个并更新了我的问题,附上了输出结果。 - dredbound
1个回答

3
如果您只想列出目录内容,则可以通过SSH发送一些命令。
Bash:
ssh 192.168.122.24 ls /tmp

如果你想在你的问题中使用"cd"命令:

ssh 192.168.122.24 "cd /tmp; ls"

Python脚本示例:

import subprocess

HOST = 'server'
PORT = '111'
USER = 'user'
CMD = 'cd /tmp; ls'

process = subprocess.Popen(['ssh', '{}@{}'.format(USER, HOST),
                            '-p', PORT, CMD], 
                           shell=False,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE)
result = process.stdout.readlines()

if not result:
    err = process.stderr.readlines()
    print('ERROR: {}'.format(err))
else:
    print(result)

1
非常好用,非常感谢!我会研究一下并找出为什么我的代码没有起作用。 - dredbound

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接