Python通过套接字发送命令

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4987077/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 18:28:12  来源:igfitidea点击:

Python sending command over a socket

pythonclientsubprocessexecution

提问by AustinM

I'm having a bit of trouble. I want to create a simple program that connects to the server and executes a command using subprocess then returns the result to the client. It's simple but I can't get it to work. Right now this is what I have: client:

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


import sys, socket, subprocess
conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = sys.argv[1]
port = int(sys.argv[2])
socksize = 1024
conn.connect((host, port))
while True:
    shell = raw_input("$ ")
    conn.send(shell)
    data = conn.recv(socksize)
    #msglen = len(data)
    output = data
    iotype = subprocess.PIPE
    cmd = ['/bin/sh', '-c', shell]
    proc = subprocess.Popen(cmd, stdout=iotype).wait()
    stdout,stderr = proc.communicate()
    conn.send(stdout)
    print(output)
    if proc.returncode != 0:
        print("Error")

server:

服务器:


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()

采纳答案by Paulo Scardine

Danger, Will Robinson!!!

危险,威尔罗宾逊!!!

Do you really want to send commands in clear text without authentication over the network? It is very, very dangerous.

您真的想在没有网络身份验证的情况下以明文形式发送命令吗?这是非常非常危险的。

Do it over SSH with paramiko.

使用paramiko通过 SSH完成

Alright I've heard this answer too many times. I don't want to use SSH I'm just building it to learn more about sockets. I'm not going to actually use this if I want to send commands to a system. – AustinM

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

There is no way I could infer this noble quest from your question. :-)

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

The sockets module is a thin layer over the posix library; plain sockets is tedious and hard to get right. As of today (2014), asynchronous I/O and concurrency are not among Python's strongest traits - 3.4 is starting to change that but libraries will lag behind for a while. My advice is to spent your time learning some higher level API like Twisted (twistedmatrix.com/trac). If you are really interested in the low level stuff, dive in the project source.

sockets 模块是 posix 库上的一个薄层;普通的套接字很乏味,而且很难弄对。截至今天(2014 年),异步 I/O 和并发性并不是 Python 最强大的特性之一 - 3.4 开始改变这一点,但库将落后一段时间。我的建议是花时间学习一些更高级的 API,比如 Twisted ( twistedmatrix.com/trac)。如果您真的对低级内容感兴趣,请深入研究项目源代码。

Alright. Any idea on how I could use twisted for this type of thing? – AustinM

好吧。关于如何将扭曲用于此类事情的任何想法?– AustinM

Look at twistedmatrix.com/documents/current/core/examples/#auto2

查看twistedmatrix.com/documents/current/core/examples/#auto2

回答by Greg Hewgill

It's unclear why you are using subprocess.Popen()for the same command in both the client and the server. Here's an outline of what I would try to do (pseudocode):

目前尚不清楚您为什么subprocess.Popen()在客户端和服务器中使用相同的命令。这是我将尝试做的事情的概述(伪代码):

client

客户

while True:
    read command from user
    send command to server
    wait for and then read response from server
    print response to user

server

服务器

while True:
    wait for and then read command from client
    if command is "killsrv", exit
    execute command and capture output
    send output to client

回答by Shoeb Lakdawala

Well I can understand your frustration Austin; I was in the same boat. However trial and error at last worked out. Hopefully you were looking for this:

好吧,我能理解你对奥斯汀的沮丧;我在同一条船上。然而,反复试验终于成功了。希望你正在寻找这个:

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)

回答by bstpierre

The problem with your code is this line (in both client and server):

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

proc = subprocess.Popen(cmd, stdout=iotype).wait()
stdout,stderr = proc.communicate()

You are calling waiton the Popenobject, which means that the variable procis getting an int (returned by wait) instead of a Popenobject. You can just get rid of the wait-- since communicatewaits for the process to end before returning, and you aren't checking the exit code anyway, you don't need to call it.

您正在调用waitPopen对象,这意味着该变量proc正在获取一个 int(由 返回wait)而不是一个Popen对象。您可以摆脱wait-- 因为communicate在返回之前等待进程结束,并且无论如何您都没有检查退出代码,因此您不需要调用它。

Then, in your client, I don't think you even need the subprocess calls, unless you're running some command that the server is sending back.

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