Python отправляет команду через сокет - PullRequest
5 голосов
/ 14 февраля 2011

У меня небольшая проблема. Я хочу создать простую программу, которая подключается к серверу и выполняет команду с использованием подпроцесса, а затем возвращает результат клиенту. Это просто, но я не могу заставить его работать. Прямо сейчас это то, что у меня есть: Клиент:


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

Сервер:


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

Ответы [ 4 ]

7 голосов
/ 14 февраля 2011

Опасно, Уилл Робинсон !!!

Вы действительно хотите отправлять команды в виде открытого текста без аутентификации по сети?Это очень, очень опасно.

Сделайте это по SSH с paramiko .

Хорошо, я слышал этот ответ слишком много раз.Я не хочу использовать SSH, я просто строю его, чтобы узнать больше о сокетах.Я не собираюсь использовать это на самом деле, если я хочу отправлять команды в систему.- AustinM

Я никак не могу вывести этот благородный квест из твоего вопроса.: -)

Модуль сокетов представляет собой тонкий слой поверх библиотеки posix;простые розетки утомительны и трудно получить права.На сегодняшний день (2014) асинхронный ввод-вывод и параллелизм не являются одними из самых сильных черт Python - 3.4 начинает меняться, но библиотеки на некоторое время отстают.Мой совет - потратить ваше время на изучение API более высокого уровня, такого как Twisted ( twistedmatrix.com / trac ).Если вы действительно заинтересованы в материалах низкого уровня, погрузитесь в источник проекта.

Хорошо.Любая идея о том, как я мог бы использовать витой для этого типа вещей?- AustinM

Посмотрите twistedmatrix.com / Documents / current / core / examples / # auto2

3 голосов
/ 25 мая 2011

Ну, я могу понять ваше разочарование, Остин;Я был в одной лодке.Однако метод проб и ошибок наконец-то сработал.Надеюсь, вы искали это:

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)
1 голос
/ 14 февраля 2011

Неясно, почему вы используете subprocess.Popen() для одной и той же команды как на клиенте, так и на сервере.Вот схема того, что я хотел бы сделать (псевдокод):

клиент

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
0 голосов
/ 25 мая 2011

Проблема с вашим кодом в этой строке (как на клиенте, так и на сервере):

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

Вы вызываете wait для объекта Popen, что означает, что переменная procполучение int (возвращаемого wait) вместо Popen объекта.Вы можете просто избавиться от wait - поскольку communicate ожидает завершения процесса, прежде чем вернуться, и вы все равно не проверяете код выхода, вам не нужно его вызывать.

Тогда в вашем клиенте я не думаю, что вам даже нужны вызовы подпроцесса, если только вы не запускаете какую-то команду, которую сервер отправляет обратно.

...