【问题标题】:Why do some Unix commands not work when called from inside Python? (command not found)为什么从 Python 内部调用某些 Unix 命令时不起作用? (找不到命令)
【发布时间】:2013-01-14 02:29:03
【问题描述】:

我经常希望在 Python 中执行 Unix 命令,但最近发现有些命令找不到。一个例子是“限制”命令:

$ echo $SHELL
/bin/tcsh
$ limit vmemoryuse 1000m
$ python
Python 2.7.3 (default, Aug  3 2012, 20:09:51) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-50)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.system("echo $SHELL")
/bin/tcsh
0
>>> os.system("limit vmemoryuse 1000m")
sh: limit: command not found
32512
>>>

另一个例子是“setenv”命令。为什么这些命令在 Python 中不起作用?我曾尝试同时使用“os”和“subprocess”模块,但均未成功。有人知道另一个模块或方法可以让我从 Python 内部成功调用这些命令吗?

【问题讨论】:

    标签: python shell unix command


    【解决方案1】:

    那是因为有些 shell 命令并不是真正的程序,而是内部的 shell 命令。

    经典的例子是cd:如果它是一个外部程序,它会改变新进程的当前目录,而不是shell的那个,所以它不能是一个外部程序。

    大致来说有两种内部shell命令:

    1. 为了效率而由 shell 实现的命令,但它仍然作为独立程序存在:truefalsetestsleep...
    2. 更改 shell 环境的命令,因此无法从子进程执行:cdumasksetenvulimit...

    第一类中的命令是特定于 shell 的。第二类的命令,没那么多。

    有关详细信息,请参阅相关 shell 的手册页(例如man bash)。

    如果您想了解特定的命令运行:

    $ type -a <command>
    

    Type是一个bashism,我不知道tcsh中的等价物,但是which是一个外部程序,所以这样:

    $ which -a <command>
    

    将显示您的命令是否作为外部程序存在,但它对 shell 内部结构一无所知。

    如果您需要 Python 程序中的内部命令(上述类型 2)的功能,则需要使用相关的系统调用。希望它已经在某些模块中可用。如果没有,您需要用 C 编写自己的包装器。

    关于你的具体命令:

    • 环境(setenvgetenv)可以通过os.environos.getenvos.putenv 等进行操作。
    • 有关进程限制 (limit),请查看 resource 模块。

    【讨论】:

    • 可以通过执行 shell 本身并在 shell 相关参数中传递所需的命令来发出不属于第 2 组的命令。对于 tcsh "-c" 似乎很有希望。
    • @guidot:是的,他们可以,但这可能无法达到您的预期。想想os.system('sh -c cd /tmp'),这将改变子进程的环境,但父进程将保持不变。解决方案是找到并调用等效的系统调用:如果它已经被 python 包装了,就调用它;如果没有,您将不得不编写一个 C 模块来完成这项工作)。
    猜你喜欢
    • 1970-01-01
    • 2014-09-28
    • 2020-10-19
    • 2018-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多