【问题标题】:When should you use system(3) to run an external process?什么时候应该使用 system(3) 来运行外部进程?
【发布时间】:2020-10-13 05:49:53
【问题描述】:

C 提供标准函数system 来使用shell 运行子进程,许多语言也提供类似的函数,例如AWKPerl(带有单个参数)和@ 987654324@。有时这些函数criticized 不适合一般使用,无论是在security grounds 上还是因为外壳不可移植或is not the one used interactively

其他一些语言似乎也同意:它们只提供一种在没有 shell 的情况下运行进程的方法,例如 Java(它标记任何单个字符串参数本身)和 Tcl。 Python 提供了direct wrappersophisticated replacement,可以避免使用shell 并明确推荐后者(如does the user community)。

当然,对于许多应用程序来说,shell 是不必要的复杂性;运行外部进程可能会带来deadlockorphan processes、不明确的退出状态和file descriptor sharing 等问题,并且在运行mkdirecho $VAR 等情况下是不必要的。但是,假设 system 的存在是有原因的,什么时候它是合适的工具?

【问题讨论】:

    标签: python c os.system


    【解决方案1】:

    对于 C 和 Python(使用 实际 C system(3))还有其他警告。 system 的 POSIX specifies 附加行为:它忽略 SIGINTSIGQUIT 并在其执行期间阻止 SIGCHLD。理由是用户(可以从终端发送SIGINTSIGQUIT)在执行期间是interacting with the subprocess,而不是父进程,并且system 必须为其子进程处理SIGCHLD,而不应用程序的干扰。

    这直接暗示了问题的答案:只有在以下情况下才适合使用system

    1. 用户直接要求执行特定的 shell 命令(例如!less),并且
    2. 应用程序不需要对在此期间退出的任何其他子进程做出反应(例如,它不应该是多线程的)。

    如果不满足#1,用户可能会发送一个终端信号,期望它终止整个进程并让它只杀死(如果不是不可见的话,意外的)子进程。 Linux 手册页特别注意using it in a loop,用户不能中断。可能会注意到孩子带着信号退出并重新提升它,但这是不可靠的,因为某些程序(例如,Python)exit 在收到某些信号时而不是重新提升 表明它们退出的原因 - 并且因为 shell(由 system 强制!)将退出状态与信号终止状态混为一谈

    在 Python 中,错误处理问题因os.system 遵循 C 退出状态(读取:错误代码)约定而不是将失败报告为 异常,邀请用户忽略孩子的退出状态。

    【讨论】:

    • 当然,在 Python 中,没有任何借口可以使用 os.system,因为所有用例都可以使用 subprocess.run
    【解决方案2】:

    答案很简单(理论上),因为它与适用于许多其他编程问题的答案相同:当system() 使程序员的生活更轻松,并且让用户的生活不再困难时,使用它是合适的。

    然而,发现这种情况是否属实需要相当大的判断力,而且我们可能并不总是能做到这一点。但是,编程中的许多判断调用也是如此。

    由于大多数 shell 都是用 C 编写的,所以没有理由原则上为什么使用 system() 完成的任何事情都离不开它。然而,有时它需要一大堆代码来完成通过调用 shell 可以在一行中完成的事情。这同样适用于popen(),我猜它提出了完全相同的问题。

    使用system() 会引起可移植性、线程安全和信号管理问题。

    不幸的是,我的经验是system() 给程序员带来最大好处的情况恰恰是它最不便携的情况。

    有时像这样的担忧会提出不同的方法,有时它们无关紧要——这取决于应用程序。

    【讨论】:

      猜你喜欢
      • 2023-04-02
      • 2011-04-15
      • 2017-04-10
      • 2012-03-19
      • 2018-05-12
      • 2018-12-11
      • 1970-01-01
      • 2022-09-28
      • 2019-09-23
      相关资源
      最近更新 更多