如何从Python执行程序或调用系统命令

如何从Python执行程序或调用系统命令,python,shell,terminal,subprocess,command,Python,Shell,Terminal,Subprocess,Command,如何从Python脚本中调用外部命令(就像我在Unix shell或Windows命令提示符下键入命令一样) import os os.system("your command") 请注意,这是危险的,因为命令未被清除。关于“os”和“sys”模块的相关文档,我将由您自行决定。有一组函数(exec*和spawn*)将执行类似的操作 import os cmd = 'ls -al' os.system(cmd) 如果要返回命令的结果,可以使用。但是,自版本2.6以来,这一点已被弃用,取而代之的

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

import os
os.system("your command")
请注意,这是危险的,因为命令未被清除。关于“os”和“sys”模块的相关文档,我将由您自行决定。有一组函数(exec*和spawn*)将执行类似的操作

import os
cmd = 'ls -al'
os.system(cmd)
如果要返回命令的结果,可以使用。但是,自版本2.6以来,这一点已被弃用,取而代之的是,其他答案已经很好地涵盖了这一点。

使用标准库中的模块:

导入子流程
子进程运行([“ls”,“-l”])
over的优点是它更灵活(您可以得到、更好的等等)

甚至建议使用
子流程

子流程
模块为生成新流程和检索其结果提供了更强大的工具;使用该模块比使用此功能更可取。有关一些有用的配方,请参阅文档中的部分

在Python3.4及更早版本上,使用
子流程.call而不是
。run

子流程调用([“ls”,“-l”])
我建议使用模块而不是os.system,因为它可以为您进行shell转义,因此更安全

subprocess.call(['ping', 'localhost'])
使用

…或者对于一个非常简单的命令:

import os
os.system('cat testfile')

os.system
还可以,但有点过时了。它也不是很安全。相反,请尝试
子流程
<代码>子进程
不直接调用sh,因此比操作系统更安全


获取更多信息。

这里总结了调用外部程序的方法以及每种方法的优缺点:

  • os.system(“带有args的some_命令”)
    将命令和参数传递给系统的shell。这很好,因为您实际上可以以这种方式一次运行多个命令,并设置管道和输入/输出重定向。例如:

    os.system("some_command < input_file | another_command > output_file")  
    
    而不是:

    print os.popen("echo Hello World").read()
    
    但是,将所有选项放在一个统一的类中,而不是4个不同的popen函数中,这很好。看

  • 来自
    子流程
    模块的
    调用
    函数。这基本上与
    Popen
    类类似,接受所有相同的参数,但它只是等待命令完成并给出返回代码。例如:

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

  • 如果您使用的是Python3.5或更高版本,则可以使用新函数,该函数与上述函数非常类似,但更灵活,在命令执行完毕后返回一个对象

  • os模块还具有C程序中的所有fork/exec/spawn函数,但我不建议直接使用它们

  • 子流程
    模块可能就是您所使用的模块

    最后,请注意,对于所有方法,您将最终命令作为字符串传递给shell执行,并负责转义它如果您传递的字符串的任何部分不能完全信任,则会产生严重的安全隐患。例如,如果用户正在输入字符串的某些/任何部分。如果不确定,请仅对常量使用这些方法。为了给你一个暗示,考虑这个代码:

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

    想象一下,用户输入了“我妈妈不爱我&&rm-rf/”这可能会擦除整个文件系统。

    典型实现:

    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()
    这里还有一个前面没有提到的区别

    subprocess.Popen
    将作为子进程执行。在我的例子中,我需要执行需要与另一个程序通信的文件

    我尝试了子流程,执行成功。然而,我无法与他沟通。 当我从终端运行时,一切正常

    还有一点: (注意:kwrite的行为与其他应用程序不同。如果您使用Firefox尝试以下操作,结果将不一样。)

    如果尝试操作系统(“kwrite”),程序流将冻结,直到用户关闭kwrite。为了克服这个问题,我尝试了
    os.system(konsole-eKwrite)
    。这次程序继续运行,但kwrite成为了控制台的子进程


    任何运行kwrite的人都不是子进程(即,在系统监视器中,它必须显示在树的最左侧边缘)。

    有关将子进程与调用进程分离(在后台启动子进程)的一些提示

    假设您想从CGI脚本开始一个长任务。也就是说,子进程应该比CGI脚本执行进程活得更长

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

    import subprocess
    import sys
    
    # Some code here
    
    pid = subprocess.Popen([sys.executable, "longtask.py"]) # Call subprocess
    
    # Some more code here
    
    这里的想法是,在longtask.py完成之前,您不希望在“callsubprocess”行中等待。但不清楚示例中的“这里有更多代码”一行之后会发生什么

    我的目标平台是FreeBSD,但开发是在Windows上进行的,所以我首先在Windows上面对这个问题

    在Windows(WindowsXP)上,在LongtTask.py完成其工作之前,父进程不会完成。这不是你想要的CGI脚本。这个问题不是Python特有的;在PHP社区中,问题是相同的

    解决方案是将分离的_进程传递给Windows API中的底层CreateProcess函数。 如果您碰巧安装了pywin32,则可以从Win32 Process模块导入该标志,否则应自行定义:

    DETACHED_PROCESS = 0x00000008
    
    pid = subprocess.Popen([sys.executable, "longtask.py"],
                           creationflags=DETACHED_PROCESS).pid
    
    /*UPD 2015.10.27@eryksun在下面的评论中指出,语义正确的标志是CREATE_NEW_CONSOLE(0x00000010)*/DETACHED_PROCESS = 0x00000008 pid = subprocess.Popen([sys.executable, "longtask.py"], creationflags=DETACHED_PROCESS).pid
    pid = subprocess.Popen([sys.executable, "longtask.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
    
    child = pexpect.spawn('ftp 192.168.0.24')
    
    child.expect('(?i)name .*: ')
    
    child.sendline('anonymous')
    
    child.expect('(?i)password')
    
    >>> subprocess.check_output(["ls", "-l", "/dev/null"])
    'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\n'
    
    from fabric.operations import local
    result = local('ls', capture=True)
    print "Content:/n%s" % (result, )
    
    from sh import vgdisplay
    print vgdisplay()
    print vgdisplay('-v')
    print vgdisplay(v=True)
    
    from subprocess import Popen
    
    proc = Popen(['ls', '-l'])
    if proc.poll() is None:
        proc.kill()
    
    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()
    
    >>> 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
    [<Response 'uptime'>]
    
    import subprocess
    subprocess.run(['ls', '-l'])
    
    import shlex
    import subprocess
    subprocess.run(shlex.split('ls -l'))
    
    from plumbum.cmd import ifconfig
    print(ifconfig['wlan0']())
    
    from sh import ifconfig
    print(ifconfig('wlan0'))
    
    >>> 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)
    
    ex('echo hello shell.py') | "awk '{print $2}'"
    
    import os
    os.system('ls')
    
    import subprocess
    subprocess.check_call('ls')
    
    import subprocess
    r = subprocess.check_output('ls')
    
    >>> from plumbum import local
    >>> ls = local["ls"]
    >>> ls
    LocalCommand(<LocalPath /bin/ls>)
    >>> 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
    
    import os
    
    cmd = 'ls -al'
    
    os.system(cmd)
    
    # 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
    
    #!/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)
    
    +--------------------------------------+------------+------+
    | 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 |
    +--------------------------------------+------------+------+
    
    27a74fcd-37c0-4789-9414-9531b7e3f126
    
    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
    
    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
    
    ls_cmd = plumbum.local("ls -l") # Get command
    ls_cmd() # Run command
    
    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.operations.local('ls -l') # Run command as normal
    fabric.operations.local('ls -l', capture = True) # Run command and receive output
    
    r = envoy.run("ls -l") # Run command
    r.std_out # Get output
    
    >>> from subprocess import run
    >>> from shlex import split
    >>> completed_process = run(split('python --version'))
    Python 3.8.8
    >>> completed_process
    CompletedProcess(args=['python', '--version'], returncode=0)
    
    >>> from subprocess import run
    >>> from shlex import split
    >>> completed_process = run(split('python --version'))
    Python 3.8.8
    >>> completed_process
    CompletedProcess(args=['python', '--version'], returncode=0)
    
    >>> completed_process.args
    ['python', '--version']
    >>> completed_process.returncode
    0
    
    >>> from subprocess import PIPE
    >>> completed_process = run(shlex.split('python --version'), stdout=PIPE, stderr=PIPE)
    >>> completed_process.stdout
    b'Python 3.8.8\n'
    >>> completed_process.stderr
    b''
    
    >>> import textwrap
    >>> args = ['python', textwrap.__file__]
    >>> cp = run(args, stdout=subprocess.PIPE)
    >>> cp.stdout
    b'Hello there.\n  This is indented.\n'
    
    def run(*popenargs, input=None, timeout=None, check=False, **kwargs):
    
    >>> 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(args, *, stdin=None, input=None, stdout=None, stderr=None, 
    shell=False, cwd=None, timeout=None, check=False, encoding=None, 
    errors=None)
    
    
    def __init__(self, args, bufsize=-1, executable=None,
                 stdin=None, stdout=None, stderr=None,
                 preexec_fn=None, close_fds=True,
                 shell=False, cwd=None, env=None, universal_newlines=None,
                 startupinfo=None, creationflags=0,
                 restore_signals=True, start_new_session=False,
                 pass_fds=(), *, user=None, group=None, extra_groups=None,
                 encoding=None, errors=None, text=None, umask=-1, pipesize=-1):
    
    
    subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, 
    stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None,
    env=None, universal_newlines=None, startupinfo=None, creationflags=0, 
    restore_signals=True, start_new_session=False, pass_fds=(), *, group=None, 
    extra_groups=None, user=None, umask=-1, encoding=None, errors=None, 
    text=None)
    
    import os
    cmd = "your command"
    os.system(cmd)
    
    import subprocess
    subprocess.run("ls -a", shell=True)
    
    import subprocess
    subprocess.run(["help"])
    subprocess.run(["ls", "-a"])
    
    import subprocess
    result = subprocess.run(["ls", "-a"], capture_output=True, text=True)
    if "stackoverflow-logo.png" in result.stdout:
        print("You're a fan!")
    else:
        print("You're not a fan?")
    
    if result.returncode == 127: print("The program failed for some weird reason")
    elif result.returncode == 0: print("The program succeeded")
    else: print("The program failed unexpectedly")
    
    result.check_returncode()
    
    result = subprocess.run(..., check=True)
    
    result = subprocess.run(..., stderr=subprocess.STDOUT)
    
    import subprocess
    import shlex
    subprocess.run(shlex.split("ls -a"))