【发布时间】:2021-03-18 17:39:57
【问题描述】:
我对从 python 代码调用 bash 感到困惑。
我写了一个小脚本,当从 python 调用 bash 时显示奇怪的行为:
import subprocess
def check_output ( command,**w ):
print( '\n>>> %s'%command )
try :
return subprocess.check_output( command,**w ).decode()
except Exception as e :
return str( e )
print( check_output( ['ls','-l']))
print( check_output( ['ls','-l',';','ls','-a']))
print( check_output( 'ls -l' ))
print( check_output( 'ls -l ; ls -a' ))
print( check_output( ['echo','99'],shell=1))
print( check_output( ['echo','11',';','echo','22'],shell=1))
print( check_output( 'echo 33 ; echo 44',shell=1 ))
还有输出:
>>> ['ls', '-l']
total 124
-rwxrwxrwx 1 root root 59 Mar 22 09:57 main.py
-rwxrwxrwx 1 root root 3885 Mar 17 17:30 README.md
drwxrwxrwx 0 root root 4096 Mar 22 10:33 src
-rwxrwxrwx 1 root root 36 Mar 22 09:57 sub.c
drwxrwxrwx 0 root root 4096 Mar 22 10:33 test
>>> ['ls', '-l', ';', 'ls', '-a']
ls: cannot access ';': No such file or directory
ls: cannot access 'ls': No such file or directory
Command '['ls', '-l', ';', 'ls', '-a']' returned non-zero exit status 2.
>>> ls -l
[Errno 2] No such file or directory: 'ls -l': 'ls -l'
>>> ls -l ; ls -a
[Errno 2] No such file or directory: 'ls -l ; ls -a': 'ls -l ; ls -a'
>>> ['echo', '99']
>>> ['echo', '11', ';', 'echo', '22']
>>> echo 33 ; echo 44
33
44
第一个和最后一个命令如我所料,但其他命令对我来说似乎很奇怪。
多个命令分隔符 ; 似乎根据参数 shell 表现不同。还有串联的命令...
顺便说一句,我使用 python 2 和 3(在 kali linux 下)得到了相同的结果。
【问题讨论】:
-
请注意,使用
shell=True通常是个坏主意。首先,但不太重要的是,它效率低下:为什么要开始复制sh并告诉it 开始gcc,而您可以直接开始gcc?其次,更重要的是,它会带来安全风险:当涉及到 shell 时,您需要担心是否有小丑告诉您的程序将编译后的文件保存为$(rm -rf ~).o;但如果没有 shell,数据中的 shell 语法是无害的。 -
至于你的问题——真正的问题与can a shell script set environment variables of the calling shell?中的问题相同;区别(父进程是 shell,这里是 Python 解释器)对问题无关紧要。
标签: python bash subprocess