我正在尝试获取python的subprocess.call方法以通过列表(由字符串序列组成)接受一些args命令,如python文档中所建议。为了在将此行为放到我的实际脚本中之前对其进行探索,我打开了IPython,运行了一些涉及shell设置和args命令不同组合的命令,并得到以下行为:
In [3]: subprocess.call(['ls', '-%sl' %'a']) total 320 drwxr-xr-x 20 Kohaugustine staff 680 Oct 15 16:55 . drwxr-xr-x 5 Kohaugustine staff 170 Sep 12 17:16 .. -rwxr-xr-x 1 Kohaugustine staff 8544 Oct 15 16:55 a.out -rwxr-xr-x 1 Kohaugustine staff 8544 Oct 3 10:28 ex1-6 -rw-r--r--@ 1 Kohaugustine staff 204 Oct 3 10:28 ex1-6.c -rwxr-xr-x 1 Kohaugustine staff 8496 Oct 3 10:15 ex1-7 -rw-r--r--@ 1 Kohaugustine staff 71 Oct 3 10:15 ex1-7.c -rwxr-xr-x 1 Kohaugustine staff 8496 Sep 12 16:22 hello -rw-r--r--@ 1 Kohaugustine staff 58 Sep 12 16:27 hello.c -rwxr-xr-x 1 Kohaugustine staff 8496 Sep 12 16:24 hello.o -rwxr-xr-x 1 Kohaugustine staff 8496 Sep 12 16:24 hello_1.o -rwxr-xr-x 1 Kohaugustine staff 8496 Sep 12 16:27 hello_2.o -rwxr-xr-x 1 Kohaugustine staff 8496 Sep 12 16:27 hello_3.o -rwxr-xr-x 1 Kohaugustine staff 8544 Oct 15 16:55 lesson_1-5 -rw-r--r--@ 1 Kohaugustine staff 185 Sep 28 10:35 lesson_1-5.c -rwxr-xr-x 1 Kohaugustine staff 8496 Sep 21 10:06 temperature.o -rw-r--r--@ 1 Kohaugustine staff 406 Sep 21 09:54 temperature_ex1-3.c -rw-r--r--@ 1 Kohaugustine staff 582 Sep 21 10:06 temperature_ex1-4.c -rw-r--r--@ 1 Kohaugustine staff 178 Sep 23 17:21 temperature_ex1-5.c -rwxr-xr-x 1 Kohaugustine staff 8496 Sep 23 17:21 temperature_ex1-5.o Out[3]: 0 In [4]: subprocess.call(['ls', '-%sl' %'a'], shell=True) a.out ex1-7 hello.c hello_2.o lesson_1-5.c temperature_ex1-4.c ex1-6 ex1-7.c hello.o hello_3.o temperature.o temperature_ex1-5.c ex1-6.c hello hello_1.o lesson_1-5 temperature_ex1-3.c temperature_ex1-5.o Out[4]: 0 In [6]: subprocess.call(['ls', '-al']) total 320 drwxr-xr-x 20 Kohaugustine staff 680 Oct 15 16:55 . drwxr-xr-x 5 Kohaugustine staff 170 Sep 12 17:16 .. -rwxr-xr-x 1 Kohaugustine staff 8544 Oct 15 16:55 a.out -rwxr-xr-x 1 Kohaugustine staff 8544 Oct 3 10:28 ex1-6 -rw-r--r--@ 1 Kohaugustine staff 204 Oct 3 10:28 ex1-6.c -rwxr-xr-x 1 Kohaugustine staff 8496 Oct 3 10:15 ex1-7 -rw-r--r--@ 1 Kohaugustine staff 71 Oct 3 10:15 ex1-7.c -rwxr-xr-x 1 Kohaugustine staff 8496 Sep 12 16:22 hello -rw-r--r--@ 1 Kohaugustine staff 58 Sep 12 16:27 hello.c -rwxr-xr-x 1 Kohaugustine staff 8496 Sep 12 16:24 hello.o -rwxr-xr-x 1 Kohaugustine staff 8496 Sep 12 16:24 hello_1.o -rwxr-xr-x 1 Kohaugustine staff 8496 Sep 12 16:27 hello_2.o -rwxr-xr-x 1 Kohaugustine staff 8496 Sep 12 16:27 hello_3.o -rwxr-xr-x 1 Kohaugustine staff 8544 Oct 15 16:55 lesson_1-5 -rw-r--r--@ 1 Kohaugustine staff 185 Sep 28 10:35 lesson_1-5.c -rwxr-xr-x 1 Kohaugustine staff 8496 Sep 21 10:06 temperature.o -rw-r--r--@ 1 Kohaugustine staff 406 Sep 21 09:54 temperature_ex1-3.c -rw-r--r--@ 1 Kohaugustine staff 582 Sep 21 10:06 temperature_ex1-4.c -rw-r--r--@ 1 Kohaugustine staff 178 Sep 23 17:21 temperature_ex1-5.c -rwxr-xr-x 1 Kohaugustine staff 8496 Sep 23 17:21 temperature_ex1-5.o Out[6]: 0 In [7]: subprocess.call(['ls', '-al'], shell = True) a.out ex1-7 hello.c hello_2.o lesson_1-5.c temperature_ex1-4.c ex1-6 ex1-7.c hello.o hello_3.o temperature.o temperature_ex1-5.c ex1-6.c hello hello_1.o lesson_1-5 temperature_ex1-3.c temperature_ex1-5.o Out[7]: 0
似乎无论何时shell = True,输出似乎都与以下内容相同:
In [9]: subprocess.call(['ls']) a.out ex1-7 hello.c hello_2.o lesson_1-5.c temperature_ex1-4.c ex1-6 ex1-7.c hello.o hello_3.o temperature.o temperature_ex1-5.c ex1-6.c hello hello_1.o lesson_1-5 temperature_ex1-3.c temperature_ex1-5.o Out[9]: 0
我很困惑;当我设置shell = True时,’-a’选项发生了什么?外壳没读吗?我已经阅读了文档,并说当shell = True时,这意味着我指定的命令将通过shell执行,因此,这意味着ls -a被馈送给shell并由shell进行操作。那么,为什么[4]和[7]中的行为呢?pydocs也没有直接解释它(尽管它确实说了当我们将shell设置为False时,什么subpprocess不会做什么)。我们让shell = False代表什么意思?操作系统中是否产生了一个新进程,而没有外壳实际控制它?
另外,如果我在[3]和[4]中使用格式字符串似乎真的很尴尬,那是因为在我将要使用subprocess.call的实际脚本中,我将不得不依赖这些格式替换为适当命令选项的字符串。我无法对某些命令行选项进行硬编码。使用纯字符串作为args也是不可能的,因为在我的脚本中将有一种方法必须对命令进行列表操作。我不知道是否有更好的方法可以解决此问题,所以如果有人可以提出其他建议,是否真的会有帮助。
非常感谢你!
当shell为True时,第一个参数附加到["/bin/sh", "-c"]。如果该参数是一个列表,则结果列表为
shell
["/bin/sh", "-c"]
["/bin/sh", "-c", "ls", "-al"]
也就是说,仅ls,notls -al用作-c选项的参数。-al用作外壳本身的第一个参数,而不是ls。
ls
ls -al
-c
-al
使用时shell=True,通常只需要传递一个字符串,然后让外壳程序根据外壳程序的常规分词规则对其进行拆分。
shell=True
# Produces ["/bin/sh", "-c", "ls -al"] subprocess.call("ls -al", shell=True)
就您而言,似乎根本不需要使用shell=True。