13.6 执行外部命令并获�它的输出¶
问题¶
ä½ æƒ³æ‰§è¡Œä¸€ä¸ªå¤–éƒ¨å‘½ä»¤å¹¶ä»¥Pythonå—符串的形å¼�获å�–执行结果。
解决方案¶
使用 subprocess.check_output() 函数。例如:
import subprocess
out_bytes = subprocess.check_output(['netstat','-a'])
这段代ç �执行一个指定的命令并将执行结果以一个å—节å—符串的形å¼�返回。 å¦‚æžœä½ éœ€è¦�文本形å¼�è¿”å›žï¼ŒåŠ ä¸€ä¸ªè§£ç �æ¥éª¤å�³å�¯ã€‚例如:
out_text = out_bytes.decode('utf-8')
如果被执行的命令以é�žé›¶ç �返回,就会抛出异常。 下é�¢çš„例å�æ�•获到错误并获å�–返回ç �:
try:
out_bytes = subprocess.check_output(['cmd','arg1','arg2'])
except subprocess.CalledProcessError as e:
out_bytes = e.output # Output generated before error
code = e.returncode # Return code
默认情况下,check_output() ä»…ä»…è¿”å›žè¾“å…¥åˆ°æ ‡å‡†è¾“å‡ºçš„å€¼ã€‚
å¦‚æžœä½ éœ€è¦�å�Œæ—¶æ”¶é›†æ ‡å‡†è¾“出和错误输出,使用 stderr å�‚数:
out_bytes = subprocess.check_output(['cmd','arg1','arg2'],
stderr=subprocess.STDOUT)
å¦‚æžœä½ éœ€è¦�用一个超时机制æ�¥æ‰§è¡Œå‘½ä»¤ï¼Œä½¿ç”¨ timeout å�‚数:
try:
out_bytes = subprocess.check_output(['cmd','arg1','arg2'], timeout=5)
except subprocess.TimeoutExpired as e:
...
通常�讲,命令的执行�需�使用到底层shell环境(比如sh�bash)。
一个å—ç¬¦ä¸²åˆ—è¡¨ä¼šè¢«ä¼ é€’ç»™ä¸€ä¸ªä½Žçº§ç³»ç»Ÿå‘½ä»¤ï¼Œæ¯”å¦‚ os.execve() 。
å¦‚æžœä½ æƒ³è®©å‘½ä»¤è¢«ä¸€ä¸ªshellæ‰§è¡Œï¼Œä¼ é€’ä¸€ä¸ªå—符串å�‚数,并设置å�‚æ•° shell=True .
æœ‰æ—¶å€™ä½ æƒ³è¦�Python去执行一个å¤�æ�‚çš„shell命令的时候这个就很有用了,比如管é�“æµ�ã€�I/Oé‡�定å�‘和其他特性。例如:
out_bytes = subprocess.check_output('grep python | wc > out', shell=True)
需è¦�注æ„�的是在shell䏿‰§è¡Œå‘½ä»¤ä¼šå˜åœ¨ä¸€å®šçš„安全风险,特别是当å�‚æ•°æ�¥è‡ªäºŽç”¨æˆ·è¾“入时。
这时候å�¯ä»¥ä½¿ç”¨ shlex.quote() 函数æ�¥å°†å�‚æ•°æ£ç¡®çš„用å�Œå¼•用引起æ�¥ã€‚
讨论¶
使用 check_output() 函数是执行外部命令并获�其返回值的最简�方�。
ä½†æ˜¯ï¼Œå¦‚æžœä½ éœ€è¦�对å�进程å�šæ›´å¤�æ�‚的交互,比如给它å�‘é€�è¾“å…¥ï¼Œä½ å¾—é‡‡ç”¨å�¦å¤–一ç§�方法。
这时候�直接使用 subprocess.Popen 类。例如:
import subprocess
# Some text to send
text = b'''
hello world
this is a test
goodbye
'''
# Launch a command with pipes
p = subprocess.Popen(['wc'],
stdout = subprocess.PIPE,
stdin = subprocess.PIPE)
# Send the data and get the output
stdout, stderr = p.communicate(text)
# To interpret as text, decode
out = stdout.decode('utf-8')
err = stderr.decode('utf-8')
subprocess 模�对于�赖TTY的外部命令��适用。
ä¾‹å¦‚ï¼Œä½ ä¸�能使用它æ�¥è‡ªåŠ¨åŒ–ä¸€ä¸ªç”¨æˆ·è¾“å…¥å¯†ç �的任务(比如一个ssh会è¯�)。
è¿™æ—¶å€™ï¼Œä½ éœ€è¦�使用到第三方模å�—了,比如基于著å��çš„ expect å®¶æ—�的工具(pexpect或类似的)