2013-02-12 29 views
25

Tôi đang sử dụng cuộc gọi subprocess.Popen và trong một câu hỏi khác, tôi phát hiện ra rằng tôi đã hiểu nhầm cách Python tạo các đối số cho dòng lệnh.xuất ra dòng lệnh gọi là subprocess?

Câu hỏi của tôi
Có cách nào để tìm hiểu dòng lệnh thực tế là gì?

Ví dụ Code: -

proc = subprocess.popen(....) 
print "the commandline is %s" % proc.getCommandLine() 

Làm thế nào bạn sẽ viết getCommandLine?

Trả lời

41

Tùy thuộc vào phiên bản Python bạn đang sử dụng. In Python3.3, các arg được lưu trong proc.args:

proc = subprocess.Popen(....) 
print("the commandline is {}".format(proc.args)) 

Trong Python2.7, the args not saved, nó chỉ là truyền lại cho các chức năng khác như _execute_child. Vì vậy, trong trường hợp đó, cách tốt nhất để có được những dòng lệnh là để lưu nó khi bạn có nó:

proc = subprocess.Popen(shlex.split(cmd)) 
print "the commandline is %s" % cmd 

Lưu ý rằng nếu bạn có danh sách của đối số (chẳng hạn như các loại điều được trả về bởi shlex.split(cmd), sau đó bạn có thể khôi phục lại chuỗi dòng lệnh, cmd sử dụng chức năng không có giấy tờ subprocess.list2cmdline:

In [14]: import subprocess 

In [15]: import shlex 

In [16]: cmd = 'foo -a -b --bar baz' 

In [17]: shlex.split(cmd) 
Out[17]: ['foo', '-a', '-b', '--bar', 'baz'] 

In [18]: subprocess.list2cmdline(['foo', '-a', '-b', '--bar', 'baz']) 
Out[19]: 'foo -a -b --bar baz' 
+0

Tôi đang ở phiên bản 2.6. Và trong ít nhất là 2.6 list2cmdline không có giấy tờ, vì nó không hoạt động: đối với '--arg = foo bar' những gì python ACTUALLY làm là '--arg = "foo bar"' nhưng list2cmdline cho là '' --arg = foo bar "'... nhưng cảm ơn. –

+0

Tôi nghĩ rằng vấn đề không có với 'list2cmdline', mà là' shlex.split'. 'shlex.split ('- arg =" foo bar "')' trả về một danh sách với một mục duy nhất: '['--arg = foo bar']', trong khi 'shlex.split ('- arg =" foo bar "')' phân tách chính xác các đối số: '[' --arg ',' = ',' foo bar ']'. Trong danh sách sau này 'list2cmdline' hoạt động tốt. – unutbu

+0

Nhân tiện, mô đun 'subprocess' của Python2.6 sử dụng' list2cmdline' để chuyển 'args' thành một danh sách bất cứ khi nào' args' không phải là một chuỗi để nó hoạt động theo nghĩa mà bạn đang thấy là giá trị trả về ' list2cmdline (args) 'là chính xác những gì đang được chuyển sang' execvp * 'hoặc tương đương với Windows. – unutbu

2

câu trả lời đúng cho câu hỏi của tôi thực sự là có IS không có dòng lệnh. Điểm của tiến trình con là nó thực hiện mọi thứ thông qua IPC. List2cmdline làm gần như có thể được mong đợi, nhưng trong thực tế điều tốt nhất để làm là nhìn vào danh sách "args", và chỉ biết rằng đó sẽ là argv trong chương trình được gọi.

+2

['list2cmdline()'] (https: // hg.python.org/cpython/file/f38489a3394f/Lib/subprocess.py#l541) chỉ hữu dụng trên Windows cho các ứng dụng tương thích với cách MS C runtime phân tích cú pháp dòng lệnh. Nó chuyển đổi một danh sách các đối số thành một chuỗi được chuyển tới 'CreateProcess()'. ['cmd.exe' sử dụng các quy tắc khác nhau] (http://stackoverflow.com/q/27864103/4279). Trên POSIX danh sách được chuyển trực tiếp đến 'os.execve()' (+/- os.fsencode()). – jfs