我尝试使用Python创建 true 交互式远程shell。当我说的是真的时,我的意思是我不想只执行一个命令并发送结果 - 我已经开始工作了。我也不想通过让服务器解释目录更改或者不解释目录来抽象执行单个命令。
我正在尝试让客户端启动交互式/bin/bash
并让服务器发送命令,然后由同一个持久shell执行。例如,如果我运行cd /foo/bar
,那么pwd
将返回/foo/bar
,因为我将与相同的bash shell进行交互。
这里有一些精简的示例代码,目前只执行单个命令...
# client.py
import socket
import subprocess
s = socket.socket()
s.connect(('localhost', 1337))
while True:
cmd = s.recv(1024)
# single command execution currently (not interactive shell)
results = subprocess.Popen(cmd, shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
stdin=subprocess.PIPE)
results = results.stdout.read() + results.stderr.read()
s.sendall(results)
# server.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('localhost', 1337))
s.listen(5)
conn, _ = s.accept()
while True:
cmd = raw_input('> ').rstrip()
conn.send(cmd)
results = conn.recv(4096)
print results
我尝试了许多解决方案,但都没有奏效。子进程模块有一个通信方法,但它在单个命令后杀死shell。我真的希望能够用stdlib实现这一目标,但在阅读this thread之后我已经看过了pexpect模块。但是,我也无法做到这一点?它看起来并不像它的主要用例是创建交互式shell,而是捕获特定的命令行输出以进行交互。我甚至无法使用pexpect进行单一命令执行......
import pexpect, sys
proc = pexpect.spawn('/bin/bash')
proc.logfile = sys.stdout
proc.expect('$ ')
proc.sendline('pwd\n')
如果有人可以提供帮助,我将不胜感激,我觉得可能有一种方法可以多线程并用子进程生成/bin/bash -i
,然后一些如何写入stdin并从stdout读取?在此先感谢,对不起。
答案 0 :(得分:0)
尝试以下代码:
# client.py
import socket
import subprocess
s = socket.socket()
s.connect(('localhost', 1337))
process = subprocess.Popen(['/bin/bash', '-i'],
stdout=s.makefile('wb'), stderr=subprocess.STDOUT,
stdin=s.makefile('rb'))
process.wait()
# server.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('localhost', 1337))
s.listen(5)
conn, _ = s.accept()
fp = conn.makefile('wb')
proc1 = subprocess.Popen('cat', stdin=conn.makefile('rb'))
while True:
fp.write(sys.stdin.read(4096))
proc1.wait()