Python通过套接字发送命令

Python通过套接字发送命令,python,client,subprocess,execution,Python,Client,Subprocess,Execution,我有点麻烦。我想创建一个简单的程序,该程序连接到服务器并使用subprocess执行命令,然后将结果返回给客户机。这很简单,但我无法让它工作。这就是我现在所拥有的: 客户: 服务器: import sys, socket, subprocess host = '' port = 50106 socksize = 1024 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((host, por

我有点麻烦。我想创建一个简单的程序,该程序连接到服务器并使用subprocess执行命令,然后将结果返回给客户机。这很简单,但我无法让它工作。这就是我现在所拥有的: 客户:

服务器:


import sys, socket, subprocess
host = ''               
port = 50106
socksize = 1024

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
print("Server started on port: %s" %port)
s.listen(1)
print("Now listening...\n")
conn, addr = s.accept()
while True:
    print 'New connection from %s:%d' % (addr[0], addr[1])
    data = conn.recv(socksize)
    cmd = ['/bin/sh', '-c', data]
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE).wait()
    stdout,stderr = cmd.communicate()
    if not data:
        break
    elif data == 'killsrv':
        sys.exit()

危险,威尔·罗宾逊

是否确实要在不通过网络进行身份验证的情况下以明文形式发送命令?这是非常非常危险的

用SSH完成


好吧,这个答案我听了太多次了。我不想使用SSH,我只是构建它来了解更多关于套接字的信息。如果我想向系统发送命令,我不会实际使用它奥斯汀

我无法从你的问题中推断出这一崇高的追求。:-)

sockets模块是posix库上的一个薄层;普通套接字很乏味,很难正确使用。截至今天(2014年),异步I/O和并发性并不是Python最强大的特性之一——3.4开始改变这一点,但库将落后一段时间。我的建议是花时间学习一些更高级的API,比如Twisted()。如果你真的对低级的东西感兴趣,那就深入到项目源代码中去


好的。你知道我怎么用twisted来做这类事情吗奥斯汀


查看不清楚为什么要在客户端和服务器中对同一命令使用
subprocess.Popen()
。下面是我将尝试做的事情(伪代码)的概要:

客户 服务器
我能理解你的沮丧,奥斯汀;我也在同一条船上。然而,反复试验终于成功了。希望您正在寻找这个:

print "Command is:",command
op = subprocess.Popen(command, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
if op:
    output=str(op.stdout.read())
    print "Output:",output
    conn.sendall(output)

else:
    error=str(op.stderr.read())
    print "Error:",error
    conn.sendall(error)

代码的问题是这一行(在客户端和服务器中):

您正在对
Popen
对象调用
wait
,这意味着变量
proc
得到的是一个int(由
wait
返回),而不是
Popen
对象。您只需去掉
等待
——因为
通信
在返回之前等待进程结束,并且您不需要检查退出代码,因此不需要调用它


然后,在您的客户机中,我认为您甚至不需要子流程调用,除非您正在运行服务器发送回来的某个命令。

为什么不使用类似paramiko的命令呢?是的。。使用SSH实现这一点。即使使用ssh exec只能传递一个命令字符串,也必须注意正确引用参数。回溯(最后一次调用):文件“client.py”,第119行,在main()文件“client.py”,第27行,在main connect()文件“client.py”,第78行,在connect stdout中,stderr=proc.communicate()AttributeError:“int”对象没有属性“communicate”,我很确定您想要使用
proc.communicate()
cmd.communicate()
。此外,以明文发送命令似乎是一个危险的想法。你想做点什么吗?下面是:?试试这个
proc=Popen(data,stdout=PIPE,stderr=PIPE)。等等()
stdout,stderr=proc.communicate()@AustinMAlright这个答案我听了太多次了。我不想使用SSH,我只是构建它来了解更多关于套接字的信息。如果我想向系统发送命令,我不会实际使用它。@AustinM:我的建议是花时间学习一些更高级的API,比如Twisted()。如果你真的感兴趣,那就研究一下项目的来源。你知道我怎么用twisted来做这类事情吗?@PauloScardine你为什么在回答部分加上这些评论?这违背了单独注释部分的目的。@Cᴴᴀ我喜欢在答案中引用有意义的评论,这样如果用户被删除,我们就不会失去上下文。评论有点转瞬即逝,有时版主出于这样或那样的原因将其删除。
while True:
    read command from user
    send command to server
    wait for and then read response from server
    print response to user
while True:
    wait for and then read command from client
    if command is "killsrv", exit
    execute command and capture output
    send output to client
print "Command is:",command
op = subprocess.Popen(command, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
if op:
    output=str(op.stdout.read())
    print "Output:",output
    conn.sendall(output)

else:
    error=str(op.stderr.read())
    print "Error:",error
    conn.sendall(error)
proc = subprocess.Popen(cmd, stdout=iotype).wait()
stdout,stderr = proc.communicate()