在Python中调用外部命令

freshWoWer 08/19/2017. 30 answers, 2.045.096 views
python shell command subprocess external

如何从Python脚本中调用一个外部命令(就像我在Unix shell或Windows命令提示符下键入的那样)?

2 Comments
Triton Man 03/19/2015
嘿这里是一个很好的教程,整合python与shell: dreamsyssoft.com/python-scripting-tutorial/shell-tutorial.ph p
6 J.F. Sebastian 06/12/2015
@TritonMan:这不是一个好的教程。 for line in proc.stdout:使用(或者for line in iter(proc.stdout.readline, '') Python中的for line in iter(proc.stdout.readline, '')在Python 2中for line in iter(proc.stdout.readline, '') ),而不是for line in proc.stdout.readlines(): 。 请参阅Python:从subprocess.communicate()读取流式输入

30 Answers


David Cournapeau 02/14/2017.

查看标准库中的子进程模块

from subprocess import call
call(["ls", "-l"]) 

systemsystem的优点是它更加灵活(你可以得到stdout,stderr,“真正的”状态码,更好的错误处理等)。

官方文档建议使用替代os.system()的subprocess进程模块:

subprocess模块提供了更多强大的工具来产生新的流程和检索结果; 使用这个模块比使用这个函数[ os.system() ]更os.system()

subprocess文档中的“ 使用子流程模块替换旧功能 ”部分可能有一些有用的配方。

有关subprocess模块的官方文档:

5 comments
155 nosklo 05/26/2009
不明白为什么你会使用os.system,即使是快速/脏/一次。 子过程似乎好多了。
33 Liam 07/29/2010
我完全同意,子进程更好。 我只需要编写一个像这样的快速脚本就可以在Python 2.3.4的旧服务器上运行,而不需要子进程模块。
50 daonb 03/21/2012
这里是子流程文档
6 goldenmean 11/10/2013
调用(..)给我一个错误oython 2.7.6:回溯(最近调用最后):文件“E:\ Ajit \ MyPython \ synonyms同义词.py”,第27行,在<module>调用(“dir”)在文件“C:\ Python27 \ lib \ subprocess.py”中,第524行,文件“C:\ Python27 \ lib \ subprocess.py”,第948行,在_execute_child startupinfo中)WindowsError:[Error 2]系统找不到指定的文件
61 J.F. Sebastian 12/21/2013
@goldenmean:我的猜测是Windows上没有ls.exe 。 尝试call("dir", shell=True)

Eli Courtwright 04/11/2016.

以下是调用外部程序的方法以及每种方法的优点和缺点:

  1. os.system("some_command with args")将命令和参数传递到系统的shell。 这很好,因为你可以用这种方式一次运行多个命令,并设置管道和输入/输出重定向。 例如:

    os.system("some_command < input_file | another_command > output_file") 

    但是,虽然这很方便,但是您必须手动处理诸如空格之类的外壳字符的转义。另一方面,这也可以让您运行仅仅是shell命令的命令,而不是真正的外部程序。 请参阅文档

  2. stream = os.popen("some_command with args")会和os.system做同样的事情,只不过它提供了一个类似于文件的对象,可以用来访问该进程的标准输入/输出。 还有另外3种不同的popen,它们的处理方式略有不同。 如果你把所有东西都作为一个字符串传递,那么你的命令会传递给shell; 如果你把它们作为一个列表,那么你不需要担心逃脱任何事情。 请参阅文档

  3. subprocess模块的Popen类。 这是作为os.popen的替代品,但由于如此全面而具有稍微复杂的缺点。 例如,你会说:

    print subprocess.Popen("echo Hello World", shell=True, stdout=subprocess.PIPE).stdout.read() 

    代替:

    print os.popen("echo Hello World").read() 

    但是在一个统一的类中有所有的选项,而不是4个不同的popen函数是很好的。 请参阅文档

  4. 来自subprocess模块的call函数。 这基本上就像Popen类一样,并且采用了所有相同的参数,但它只是等待命令完成并给出返回码。 例如:

    return_code = subprocess.call("echo Hello World", shell=True) 

    请参阅文档

  5. 如果您使用的是Python 3.5或更高版本,则可以使用新的subprocess.run函数,该函数与上述类似,但更为灵活,并在命令执行CompletedProcess时返回CompletedProcess对象。

  6. OS模块也具有C程序中所有的fork / exec / spawn函数,但我不建议直接使用它们。

subprocess模块可能应该是你使用的。

最后,请注意,对于所有将shell以字符串的形式传递给最终命令的方法,您有责任将其转义。 如果您传递的字符串的任何部分不能完全信任,则There are serious security implications 。 例如,如果用户正在输入字符串的某个/任何部分。 如果您不确定,只能使用这些常量的方法。 给你一个暗示的提示考虑这个代码:

print subprocess.Popen("echo %s " % user_input, stdout=PIPE).stdout.read() 

并想象用户输入“我的妈妈不爱我&& rm -rf /”。

5 comments
8 Casebash 05/16/2010
你没有提到命令模块
111 Eli Courtwright 05/16/2010
@Casebash:我没有打扰提及它,因为文档指出, The subprocess module provides more powerful facilities for spawning new processes and retrieving their results. Using the subprocess module is preferable to using the commands module. The subprocess module provides more powerful facilities for spawning new processes and retrieving their results. Using the subprocess module is preferable to using the commands module. 我同样没有提到popen2模块,因为它也是过时的,它和commands模块实际上都在Python 3.0和更高版本中。 代替编辑我的答案,我会让这些评论成为提到这些模块的方式。
15 PhoebeB 11/15/2010
在这里使用子过程的大文章: doughellmann.com/PyMOTW/subprocess
11 jldupont 01/21/2012
命令模块现在已经被弃用了。
13 simao 06/12/2012
对于很多情况,你不需要直接实例化一个Popen对象,你可以使用subprocess.check_callsubprocess.check_output

EmmEff 12/10/2016.

我通常使用:

import subprocess

p = subprocess.Popen('ls', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in p.stdout.readlines():
    print line,
retval = p.wait() 

您可以自由地使用管道中的stdout数据执行所需的操作。 事实上,你可以简单地省略这些参数( stdout=stderr= ),它的行为就像os.system()

5 comments
19 J.F. Sebastian 11/16/2012
.readlines()一次读取all行,即阻塞,直到子.readlines()退出(关闭管道的末端)。 要实时阅读(如果没有缓冲问题),您可以: for line in iter(p.stdout.readline, ''): print line,
EmmEff 11/17/2012
你能否详细说一下“如果没有缓冲问题”的意思? 如果进程阻塞明确,子进程调用也会阻塞。 我原来的例子也会发生同样的情况。 关于缓冲还有什么可能发生?
9 J.F. Sebastian 11/17/2012
子进程可能会在非交互模式下使用块缓冲,而不是在线缓冲,所以p.stdout.readline() (注意:末尾没有s )在孩子填充缓冲区之前不会看到任何数据。 如果孩子没有产生太多的数据,那么输出不会是实时的。 查看Q中的第二个原因:为什么不使用管道(popen())?在这个答案中提供一些解决方法(pexpect,pty,stdbuf)
2 J.F. Sebastian 04/10/2013
@Paul:如果你的代码产生了意想不到的结果,那么你可以创建一个完整的最小代码示例来重现问题并将其作为一个新问题发布 。 提到你期望发生什么,取而代之的是什么。
2 Paul 04/11/2013
好吧把你的意见stackoverflow.com/questions/15945585/...谢谢!

newtover 07/27/2017.

一些提示将子进程从调用者中分离出来(在后台启动子进程)。

假设你想从一个CGI脚本开始一个长时间的任务,那就是子进程应该比CGI脚本的执行过程长。

子流程模块文档中的经典示例是:

import subprocess
import sys

# some code here

pid = subprocess.Popen([sys.executable, "longtask.py"]) # call subprocess

# some more code here 

这里的想法是,你不想在“调用子进程”的行中等待longtask.py完成。 但是不清楚在这个例子中'这里有更多的代码'之后会发生什么。

我的目标平台是freebsd,但开发是在Windows上,所以我首先面对Windows的问题。

在Windows(win xp)上,父进程将不会完成,直到longtask.py完成其工作。 这不是你想要的CGI脚本。 这个问题不是特定于Python,在PHP社区中的问题是一样的。

解决方法是在win API中将DETACHED_PROCESS 进程创建标志传递给底层的CreateProcess函数。 如果你碰巧安装了pywin32,你可以从win32process模块​​导入标志,否则你应该自己定义它:

DETACHED_PROCESS = 0x00000008

pid = subprocess.Popen([sys.executable, "longtask.py"],
                       creationflags=DETACHED_PROCESS).pid 

/ * UPD 2015.10.27 @eryksun在下面的注释中注意到,语义上正确的标志是CREATE_NEW_CONSOLE(0x00000010)* /

在freebsd上我们还有另外一个问题:当父进程完成时,它也完成子进程。 这不是你想要的CGI脚本。 一些实验表明,这个问题似乎在共享sys.stdout。 工作解决方案如下:

pid = subprocess.Popen([sys.executable, "longtask.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) 

我没有检查过其他平台上的代码,也不知道freebsd上的行为的原因。 如果有人知道,请分享你的想法。 在Python中开始后台进程的搜索没有任何亮点。

5 comments
maranas 04/09/2010
感谢你的回答! 我注意到在pydev + eclipse中开发py2exe应用程序的一个可能的“怪癖”。 因为eclipse的输出窗口没有终止,所以我能够知道主脚本没有被分离。 即使脚本执行完成,它仍在等待退货。 但是,当我试图编译到py2exe可执行文件,预期的行为发生(作为分离运行的进程,然后退出)。 我不确定,但可执行文件的名称不在进程列表中了。 这适用于所有方法(os.system(“start *”),os.spawnl与os.P_DETACH,subprocs等)
Alexey Lebedev 04/16/2012
Windows问题:尽管我用DETACHED_PROCESS生成了进程,当我杀死了我的Python守护进程时,由它打开的所有端口都不会释放,直到所有生成的进程终止。 WScript.Shell解决了我所有的问题。 示例: pastebin.com/xGmuvwSx
1 J.F. Sebastian 11/16/2012
您可能还需要CREATE_NEW_PROCESS_GROUP标志。 即使当眼前的孩子已经终止,也可以看到Popen在等待孩子的进程
1 eryksun 10/27/2015
以下是不正确的:“[窗口](WIN XP),父进程将不会完成,直到longtask.py完成其工作”。 父节点将正常退出,但控制台窗口(conhost.exe实例)仅在最后连接的进程退出时关闭,并且子节点可能已经继承了父节点的控制台。 在creationflags设置DETACHED_PROCESS通过防止孩子继承或创建一个控制台来避免这种情况。 如果你想要一个新的控制台,使用CREATE_NEW_CONSOLE (0x00000010)。
1 eryksun 10/27/2015
我不是说作为一个独立的进程执行是不正确的。 也就是说,您可能需要将标准句柄设置为文件,管道或os.devnull因为有些控制台程序会以其他错误退出。 当您希望子进程与父进程同时与用户交互时,创建一个新的控制台。 尝试在一个窗口中进行这两个操作会令人困惑。

sirwart 04/04/2014.

我建议使用子进程模块,而不是os.system,因为它确实shell逃脱你,因此更安全: http ://docs.python.org/library/subprocess.html

subprocess.call(['ping', 'localhost']) 
2 comments
Joe Skora 09/18/2008
而子进程将允许你轻松地附加到进程的输入/输出流等。
6 habnabit 09/18/2008
子进程不为你做shell逃脱,因为它完全避免了使用shell。 这实际上意味着启动速度要快一些,而且开销较小。

Alexandra Franks 01/26/2016.
import os
cmd = 'ls -al'
os.system(cmd) 

如果你想返回命令的结果,你可以使用os.popen 。 然而,从版本2.6开始,这被弃用,而是支持子流程模块 ,其他的答案已经被覆盖了。

3 comments
2 Fox Wilson 08/08/2014
popen 不赞成 进程。
BuvinJ 04/12/2017
添加cmd = subprocess.list2cmdline( [ 'my','list','of','tokens' ] )来处理转义。
Karlos 04/15/2017
在多个环境系统中运行时简洁地尊重本地操作系统

nimish 09/18/2008.
import os
os.system("your command") 

请注意,这是危险的,因为该命令没有清理。 我把它放在你的谷歌'os'和'sys'模块的相关文档。 有一堆函数(exec *,spawn *)会做类似的事情。


athanassis 05/28/2017.

检查“pexpect”Python库。

它允许外部程序/命令的交互式控制,甚至ssh,ftp,telnet等。你可以输入如下内容:

child = pexpect.spawn('ftp 192.168.0.24')

child.expect('(?i)name .*: ')

child.sendline('anonymous')

child.expect('(?i)password') 

Jorge E. Cardona 07/23/2013.

我总是使用fabric这样的事情:

from fabric.operations import local
result = local('ls', capture=True)
print "Content:/n%s" % (result, ) 

但是这似乎是一个很好的工具: sh (Python子进程接口)

看一个例子:

from sh import vgdisplay
print vgdisplay()
print vgdisplay('-v')
print vgdisplay(v=True) 
1 comments
2 Yauhen Yakimovich 05/23/2013
sh优于子进程模块。 它允许更好的外壳集成

Facundo Casco 12/10/2016.

如果你需要的是你所调用的命令的输出,
那么你可以使用subprocess.check_output(Python 2.7+)。

>>> subprocess.check_output(["ls", "-l", "/dev/null"])
'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\n' 

还要注意shell参数。

如果shell为True ,则指定的命令将通过shell执行。 如果您主要将Python用于其在大多数系统shell中提供的增强控制流,并且仍希望方便地访问其他shell功能(如shell管道,文件名通配符,环境变量扩展以及将〜扩展到用户的home目录。 但是,请注意,Python本身提供了许多类似shell的特性(特别是globfnmatchos.walk()os.path.expandvars()os.path.expanduser()shutil )的实现。


Usman Khan 10/28/2012.

这是我如何运行我的命令。 这个代码有你需要的一切

from subprocess import Popen, PIPE
cmd = "ls -l ~/"
p = Popen(cmd , shell=True, stdout=PIPE, stderr=PIPE)
out, err = p.communicate()
print "Return code: ", p.returncode
print out.rstrip(), err.rstrip() 
3 comments
Eric 07/23/2013
以字符串形式传递命令通常是一个坏主意
1 Adam Matan 04/02/2014
如果增加可读性,我认为硬编码命令是可以接受的。
sam 09/12/2016
谢谢。 来自Perl和Ruby的Python在运行命令时是一个PITA。 阅读很多解决方案。 像你的popen一样。

Honza Javorek 08/12/2016.

用标准库

使用子流程模块

from subprocess import call
call(['ls', '-l']) 

这是推荐的标准方式。 然而,更复杂的任务(管道,输出,输入等)可能是枯燥的构造和写作。

注: shlex.split可以帮助你解析call和其他subprocess 进程函数的命令,以防万一你不想(或者你不能!)以列表的形式提供它们:

import shlex
from subprocess import call
call(shlex.split('ls -l')) 

与外部依赖关系

如果你不介意外部依赖,使用

from plumbum.cmd import ifconfig
print(ifconfig['wlan0']()) 

这是最好的subprocess封装。 它是跨平台的,即它可以在Windows和类Unix系统上运行。 通过pip install plumbum

另一个流行的图书馆是sh

from sh import ifconfig
print(ifconfig('wlan0')) 

但是, sh放弃了对Windows的支持,所以它不像以前那么棒。 通过pip install sh


Joe 05/23/2017.

更新:

如果您的代码不需要保持与早期Python版本的兼容性,那么在Python 3.5中推荐使用subprocess.run。 它更一致,并提供与Envoy类似的易用性。 (管道不是那么简单,请看这个问题 。)

以下是文档中的一些示例。

运行一个进程:

>>> subprocess.run(["ls", "-l"])  # doesn't capture output
CompletedProcess(args=['ls', '-l'], returncode=0) 

提升失败运行:

>>> subprocess.run("exit 1", shell=True, check=True)
Traceback (most recent call last):
  ...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1 

捕获输出:

>>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE)
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0,
stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n') 

原始答案:

我建议尝试特使 。 这是一个子进程的包装,它反过来旨在取代旧的模块和功能。 特使是人类的子进程。

自述文件中的示例用法:

>>> r = envoy.run('git config', data='data to pipe in', timeout=2)

>>> r.status_code
129
>>> r.std_out
'usage: git config [options]'
>>> r.std_err
'' 

管东西也是:

>>> r = envoy.run('uptime | pbcopy')

>>> r.command
'pbcopy'
>>> r.status_code
0

>>> r.history
[] 
2 comments
4 J.F. Sebastian 10/03/2015
注意:默认情况下忽略非零退出状态的subprocess.check_call()是与subprocess.check_call()subprocess.check_output()进行比较的回归。 python -mthis“错误不应该默默地传递,除非明确的声明。
itirazimvar 09/01/2016
谢谢你们的特使比子流程更好,你们救了我一天。 命令=“ansible-playbook”playbook.yaml --extra-vars = \“esxi_host = {0} extravar1 = {1} extravar2 = {2} extravar3 = {3} \”“。format(extravar1,extravar2 ,extravar3)和r.envoy.run(命令)

Tom Fuller 05/28/2017.

有很多不同的库允许你用Python调用外部命令。 对于每个库,我都给出了一个描述,并给出了一个调用外部命令的例子。 我用作例子的命令是ls -l (列出所有文件)。 如果您想了解更多关于我列出的任何库的信息,并链接了每个库的文档。

Sources:

These are all the libraries:

希望这会帮助你决定使用哪个库:)

subprocess

子进程允许你调用外部命令,并将它们连接到它们的输入/输出/错误管道(stdin,stdout和stderr)。 子进程是运行命令的默认选择,但有时其他模块更好。

subprocess.run(["ls", "-l"]) # Run command
subprocess.run(["ls", "-l"], stdout=subprocess.PIPE) # This will run the command and return any output
subprocess.run(shlex.split("ls -l")) # You can also use the shlex library to split the command 

os

os用于“依赖于操作系统的功能”。 它也可以用来调用os.systemos.popen外部命令(注意:还有一个os.popen )。 操作系统将永远运行的shell,是一个简单的替代人不需要,或不知道如何使用subprocess.run

os.system("ls -l") # run command
os.popen("ls -l").read() # This will run the command and return any output 

sh

sh是一个子进程接口,它可以让你像调用函数一样调用程序。 如果要多次运行命令,这非常有用。

sh.ls("-l") # Run command normally
ls_cmd = sh.Command("ls") # Save command as a variable
ls_cmd() # Run command as if it were a function 

plumbum

plumbum是“脚本式”Python程序库。 你可以调用像sh函数一样的程序。 如果您想在没有外壳的情况下运行管道,则铅是非常有用的。

ls_cmd = plumbum.local("ls -l") # get command
ls_cmd() # run command 

pexpect

pexpect让你产生子应用程序,控制它们并在其输出中找到模式。 对于期望在Unix上使用tty的命令,这是对子进程的更好的选择。

pexpect.run("ls -l") # Run command as normal
child = pexpect.spawn('scp foo user@example.com:.') # Spawns child application
child.expect('Password:') # When this is the output
child.sendline('mypassword') 

fabric

fabric是一个Python 2.5和2.7库。 它允许您执行本地和远程shell命令。 结构是在安全shell(SSH)中运行命令的简单替代方法

fabric.operations.local('ls -l') # Run command as normal
fabric.operations.local('ls -l', capture = True) # Run command and receive output 

envoy

特使被称为“人类的子过程”。 它用作subprocess模块的便利包装。

r = envoy.run("ls -l") # Run command
r.std_out # get output 

commands

commands包含os.popen包装函数,但是它已经从Python 3中删除了,因为subprocess是一个更好的选择。

编辑基于JF Sebastian的评论。

4 comments
Tom Fuller 10/29/2016
我错过了吗?
3 J.F. Sebastian 11/02/2016
明确指定when以及why你更喜欢一个库比另一个库pexpect用,例如, pexpect对于希望在Unix上使用tty的命令是有用的, pexpect可以用来在不调用shell的情况下运行管道fabric是一种简单的方法通过ssh运行命令, subprocess (不像os )永远不会运行shell,除非你问 - 这是运行外部命令的默认选择,有时候你可能需要替代方法
Tom Fuller 11/02/2016
我根据您的反馈编辑了我的答案:)
1 J.F. Sebastian 11/02/2016
os “外部命令”功能是在subprocess内部实现的。 对于其他语言的人来说( system()popen()是一个通用的API)可能是有用的,他们不需要subprocess模块的全部功能,也没有时间学习如何使用subprocess.run()和其他子进程的功能。

Zuckonit 05/28/2017.

没有结果的输出:

import os
os.system("your command here") 

输出结果:

import commands
commands.getoutput("your command here")
or
commands.getstatusoutput("your command here") 
1 comments
2 Ramsharan 10/19/2013
我喜欢with output of result的部分。 我需要这个在崇高的控制台使用。

stuckintheshuck 10/10/2014.

还有

>>> from plumbum import local
>>> ls = local["ls"]
>>> ls
LocalCommand()
>>> ls()
u'build.py\ndist\ndocs\nLICENSE\nplumbum\nREADME.rst\nsetup.py\ntests\ntodo.txt\n'
>>> notepad = local["c:\\windows\\notepad.exe"]
>>> notepad()                                   # Notepad window pops up
u''                                             # Notepad window is closed by user, command returns 
1 comments
J.F. Sebastian 07/13/2015
或者添加一点魔力: from plumbum.cmd import ls, grep; output = (ls | grep['pattern'])() from plumbum.cmd import ls, grep; output = (ls | grep['pattern'])()

Ben Hoffstein 11/02/2014.

https://docs.python.org/2/library/subprocess.html

...或者一个非常简单的命令:

import os
os.system('cat testfile') 

Martin W 12/10/2016.

os.system是可以的,但有点过时。 这也不是很安全。 相反,尝试subprocesssubprocess os.system不直接调用sh,因此比os.system更安全。

在这里获取更多信息。


William Keller 12/10/2016.

os.systemos.system进程模块取代。 改用subproccess。

3 comments
14 Michael Mior 03/29/2010
也许是一个使用subprocess的例子?
5 Mark Amery 12/22/2016
鉴于被接受的答案提出了更早的subprocess和更多的细节,我认为这个答案没有任何价值。
sudo 04/23/2017
os.system什么问题? 这是最直观的,只是运行你在字符串中的东西,并没有所有的人们在接受的答案下列出的警告。

cdunn2001 01/18/2011.

如果你不想测试返回值, subprocess.check_call是很方便的。 它会引发任何错误的异常。


Atinc Delican 12/10/2016.

这里还有一个不同之处,上面没有提到。

subprocess.Popen执行一个子进程。 在我的情况下,我需要执行需要与另一个程序进行通信的文件。

我试过子程序,执行成功了。 但是不能通讯w /。 一切正常,当我从终端运行。

还有一个:(注意:kwrite的行为与其他应用程序不同,如果你在下面尝试firefox的结果将不会是一样的)

如果你尝试os.system("kwrite") ,程序流程冻结,直到用户关闭kwrite。 为了克服这个,我试着改为os.system(konsole -e kwrite) 。 这个时间程序继续流动,但kwrite成为konsole的子进程。

任何人运行kwrite不是一个子进程(即在系统监视器,它必须出现在树的最左边)


Priyankara 05/28/2017.

使用:

import os

cmd = 'ls -al'

os.system(cmd) 

操作系统 - 该模块提供了使用操作系统相关功能的便携方式。

更多的os功能, 这里是文档。

3 comments
PolarisUser 10/09/2015
有没有办法将cmd的结果推送到一个文件? 我正在卷曲一个网站,我希望它去一个文件。
user2820579 10/16/2015
这是迄今为止最简单和最强大的解决方案。 @PolarisUser你可以使用通用的linux命令: > outputfile.txt
Corey Goldberg 12/09/2015
它也被弃用。 使用子进程

Saurabh Bangad 06/11/2012.

os.system不允许你存储结果,所以如果你想在一些列表中存储结果或者subprocess.call工程。


Emil Stenström 04/30/2014.

我倾向于与shlex一起使用subprocess (来处理引用字符串的转义):

>>> import subprocess, shlex
>>> command = 'ls -l "/your/path/with spaces/"'
>>> call_params = shlex.split(command)
>>> print call_params
["ls", "-l", "/your/path/with spaces/"]
>>> subprocess.call(call_params) 

houqp 05/01/2014.

无耻的插件,我为此写了一个库:P https://github.com/houqp/shell.py

它现在基本上是popen和shlex的包装。 它还支持管道命令,因此您可以在Python中更轻松地链接命令。 所以你可以做这样的事情:

ex('echo hello shell.py') | "awk '{print $2}'" 

admire 05/28/2017.

你可以使用Popen,然后你可以检查程序的状态:

from subprocess import Popen

proc = Popen(['ls', '-l'])
if proc.poll() is None:
    proc.kill() 

检查出subprocess.Popen


IRSHAD 07/20/2016.

从openstack中子获取网络ID:

#!/usr/bin/python
import os
netid= "nova net-list | awk '/ External / { print $2 }'"
temp=os.popen(netid).read()  /* here temp also contains new line (\n) */
networkId=temp.rstrip()
print(networkId) 

nova net-list输出

+--------------------------------------+------------+------+
| ID                                   | Label      | CIDR |
+--------------------------------------+------------+------+
| 431c9014-5b5d-4b51-a357-66020ffbb123 | test1      | None |
| 27a74fcd-37c0-4789-9414-9531b7e3f126 | External   | None |
| 5a2712e9-70dc-4b0e-9281-17e02f4684c9 | management | None |
| 7aa697f5-0e60-4c15-b4cc-9cb659698512 | Internal   | None |
+--------------------------------------+------------+------+ 

print(networkId)输出print(networkId)

27a74fcd-37c0-4789-9414-9531b7e3f126 

yuval 11/27/2016.

在Linux下,如果你想调用一个独立执行的外部命令(在python脚本终止后会继续运行),你可以使用一个简单的队列作为任务假脱机程序at命令

任务假脱机程序的示例:

import os
os.system('ts ') 

有关任务假脱机程序( ts )的说明:

  1. 您可以设置要运行的并发进程数(“槽”):

    ts -S

  2. 安装ts不需要管理员权限。 您可以使用简单的源代码从源代码进行下载和编译,将其添加到您的路径,然后就完成了。


urosjarc 05/28/2017.

这是我的两分钱:在我看来,这是处理外部命令时的最佳做法。

这些是执行方法的返回值...

pass, stdout, stderr = execute(["ls","-la"],"/home/user/desktop") 

这是执行方法...

def execute(cmdArray,workingDir):

    stdout = ''
    stderr = ''

    try:
        try:
            process = subprocess.Popen(cmdArray,cwd=workingDir, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=1)
        except OSError:
            return [False, '', 'ERROR : command(' + ' '.join(cmdArray) + ') could not get executed!']

        for line in iter(process.stdout.readline, b''):

            try:
                echoLine = line.decode("utf-8")
            except:
                echoLine = str(line)

            stdout += echoLine

        for line in iter(process.stderr.readline, b''):

            try:
                echoLine = line.decode("utf-8")
            except:
                echoLine = str(line)

            stderr += echoLine

    except (KeyboardInterrupt,SystemExit) as err:
        return [False,'',str(err)]

    process.stdout.close()

    returnCode = process.wait()
    if returnCode != 0 or stderr != '':
        return [False, stdout, stderr]
    else:
        return [True, stdout, stderr] 
1 comments
ppperry 07/07/2016
死锁潜力:改用.communicate方法

Swadhikar C 05/28/2017.

在Windows中,您可以通过调用subprocess.Popen()subprocess.Popen().communicate()subprocess.Popen().wait()来导入subprocess模块并运行外部命令,如下所示:

# Python script to run a command line
import subprocess

def execute(cmd):
    """
        Purpose  : To execute a command and return exit status
        Argument : cmd - command to execute
        Return   : exit_code
    """
    process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    (result, error) = process.communicate()

    rc = process.wait()

    if rc != 0:
        print "Error: failed to execute command:", cmd
        print error
    return result
# def

command = "tasklist | grep python"
print "This process detail: \n", execute(command) 

输出:

This process detail:
python.exe                     604 RDP-Tcp#0                  4      5,660 K 

Related questions

Hot questions

Language

Popular Tags