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

2022-09-05 00:43:07

如何在Python中调用外部命令,就像我在shell或命令提示符中键入它一样?


答案 1

使用标准库中的子流程模块:

import subprocess
subprocess.run(["ls", "-l"])

subprocess.run over os.system的优点是它更灵活(你可以得到stdoutstderr“真实”状态代码,更好的错误处理等)。

甚至 os.system 的文档也建议改用:subprocess

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

在 Python 3.4 及更早版本中,请代替 :subprocess.call.run

subprocess.call(["ls", "-l"])

答案 2

调用外部程序的方法摘要,包括它们的优缺点:

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

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

    但是,虽然这很方便,但您必须手动处理shell字符(如空格等)的转义。另一方面,这也允许您运行简单的shell命令,而不是实际的外部程序。

  2. os.popen 将执行与相同的操作,只是它为您提供了一个类似文件的对象,您可以使用该对象来访问该进程的标准输入/输出。还有3种其他的popen变体,它们对i / o的处理方式略有不同。如果您将所有内容作为字符串传递,则您的命令将传递给shell;如果您将它们作为列表传递,则无需担心逃避任何内容。例:os.system

    print(os.popen("ls -l").read())
    
  3. 子进程。波彭。这是为了替代 ,但缺点是由于如此全面而稍微复杂一些。例如,你会说: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. 基本上就像类一样,并采用所有相同的参数,但它只是等到命令完成并为您提供返回代码。例如:Popen

    return_code = subprocess.call("echo Hello World", shell=True)
    
  5. subprocess.run. 仅限 Python 3.5+ 。与上述类似,但更加灵活,并在命令执行完成时返回 CompletedProcess 对象。

  6. os.fork, 与 C 语言对应物类似,但我不建议直接使用它们。os.execos.spawn

该模块可能就是您使用的内容。subprocess

最后,请注意,对于所有方法,您都将最终命令作为字符串传递给 shell,并且您负责转义它。如果传递的字符串的任何部分不能完全信任,则存在严重的安全隐患。例如,如果用户正在输入字符串的某些/任意部分。如果不确定,请仅将这些方法与常量结合使用。为了向您提示其含义,请考虑以下代码:

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

并想象用户输入一些“”的东西,这可能会擦除整个文件系统。my mama didnt love me && rm -rf /