关于python 3.x:为什么check_output可以在不设置’shell = True’的情况下工作

why check_output can work without setting 'shell=True'

https://stackoverflow.com/a/12698328/391104

上面的帖子说shell=True不应该在check_output中使用。 但是,如果不使用shell=True,我甚至无法工作。

有什么问题?

Python 3.5.1

1
2
>>> from subprocess import STDOUT, check_output
>>> check_output('ls -l', stderr=STDOUT, timeout=10)

Traceback (most recent call last): File"", line 1, in
File
"/opt/rh/rh-python35/root/usr/lib64/python3.5/subprocess.py", line
629, in check_output
**kwargs).stdout File"/opt/rh/rh-python35/root/usr/lib64/python3.5/subprocess.py", line
696, in run
with Popen(*popenargs, **kwargs) as process: File"/opt/rh/rh-python35/root/usr/lib64/python3.5/subprocess.py", line
950, in init
restore_signals, start_new_session) File"/opt/rh/rh-python35/root/usr/lib64/python3.5/subprocess.py", line
1544, in _execute_child
raise child_exception_type(errno_num, err_msg) FileNotFoundError: [Errno 2] No such file or directory: 'ls -l'

然而,

1
>>> check_output('ls -l', stderr=STDOUT, timeout=10, shell=True)

按预期工作

== AnilRedshift更新==

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# work w/o problems
try:
    subprocess.check_output("rsync -ae 'ssh -q' /tmp/hello*.txt machine:/tmp", timeout=20, shell=True)
except subprocess.TimeoutExpired as e:
    print(e)

# fail
try:
    args = shlex.split("rsync -ae 'ssh -q' /tmp/hello*.txt machine:/tmp")
    subprocess.check_output(args, timeout=20)
except subprocess.TimeoutExpired as e:
    print(e)

CalledProcessError: Command '['rsync', '-ae', 'ssh -q', '/tmp/hello*.txt', 'machine:/tmp']' returned non-zero exit status 23

当你使用shell=True时,首先发生的是你的命令是通过shell语义解析的。

在这种情况下,ls -l变为['ls', '-l']

所以,如果你想自己做这个,没有shell,你需要将命令分成arg块。

1
2
from subprocess import STDOUT, check_output
check_output(['ls', '-l'], stderr=STDOUT, timeout=10)

如果您有更复杂的命令,可以使用shlex.split作为帮助程序:

1
2
3
import shlex
args = shlex.split("ls -l")
check_output(args, stderr=STDOUT, timeout=10)