我的远程服务器上有一个长时间运行的程序,我想从 Paramiko 开始。
我知道如何在后台启动程序(例如使用
nohup
),但我的程序首先需要一些用户输入。在正常的 SSH 会话中,我会通过终端交互地传递这些内容,然后分离(Ctrl+Z、bg
、detach
),但我无法使用 Paramiko 执行此操作。
这是我迄今为止一直在尝试的:
stdin, stdout, stderr = ssh.exec_command('MyCommand', get_pty=True)
stdin.channel.send(b'MyData\r')
stdin.channel.send(b'\x1A') # This is Ctrl+Z
ssh.exec_command('bg; disown')
ssh.close()
但是当SSH连接关闭时,远程程序也会停止运行。如何将用户输入发送到我想要继续在后台运行的程序?
您当前正在两个单独的 shell 实例中执行
MyCommand
和 bg; disown
。这就是为什么 bg; disown
对 MyCommand
没有影响。
如果您确实想以这种方式模拟交互式 shell 功能,则需要在一个真实的 shell 实例中执行这两个命令。为此,您需要使用
SSHClient.invoke_shell
而不是 SSHClient.exec_command
。
虽然总的来说,这不是一个好主意。另请参阅:
Paramiko 上的 exec_command 和使用 invoke_shell() 发送有什么区别?
如果该程序是您的,请将其修改为允许从命令行获取输入。
如果无法修改它,请使用 shell 结构来提供输入,例如:
ssh.exec_command('nohup echo MyData | MyCommand >/dev/null 2>&1 &')
也许您需要在命令周围添加引号,我不确定,这里的“运算符优先级”是什么。