os.system与命令行有何不同? [英] How does os.system differ from command line?

查看:84
本文介绍了os.system与命令行有何不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么我的python解释器中的os.system('command')与终端的命令输出不同?

问题快速解释:

我有

echo $CONFPATH
/home/claramart/Datamart/Parameter

但是

os.system('echo $CONFPATH')

0

那是为什么?

详细信息:我想获取我的环境$ CONFPATH.我正在使用python3.5和ubuntu16.04.2.

Details : I want to get my environment $CONFPATH. I'm using python3.5 and ubuntu16.04.2.

我可以从命令行执行此操作:

I can do this from command line :

echo $CONFPATH
/home/claramart/Datamart/Parameter

这是我想要的答案.

从命令行将其作为python命令执行也可以:

Executing it as a python command from command line also works :

python3 -c 'import os; print(os.environ["CONFPATH"])'
/home/claramart/Datamart/Parameter

问题是,我想从我的python解释器而不是从命令行执行此命令.从我的python解释器执行它不起作用(我正在使用Pyzo4.4.1):

The thing is, I want to execute this from my python interpreter and not from command line. Executing it from my python interpreter does not work (I am using Pyzo4.4.1) :

print(os.environ["CONFPATH"])
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/lib/python3.5/os.py", line 725, in __getitem__
    raise KeyError(key) from None
KeyError: 'CONFPATH'

我认为这严格来说是我的解释器提供的,而不是python本身,因为从命令行执行python可以正常工作.而且,我可以从python解释器中获取$ PYTHONPATH,因此我想它根本无法检测到所有环境变量.

I suppose this is strictly coming from my interpreter and not python itself as the python execution from the command line worked. Moreover, I can get $PYTHONPATH from my python interpreter so I guess it simply does not detect all environment variables.

为避免这种情况并从命令行执行它,我想从python解释器作为命令行执行此操作,但是我的2个命令行执行都没有按照我想要的方式工作:

To avoid this and as executing it from command line worked, I wanted to do this as a command line execution from my python interpreter, but none of my 2 command line executions work the way I want to :

os.system('echo $CONFPATH')

0

和:

os.system("""python3 -c 'import os; print(os.environ["CONFPATH"]'""")
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python3.5/os.py", line 725, in __getitem__
    raise KeyError(key) from None
KeyError: 'CONFPATH'
256

再一次,在这两种情况下,它确实都适用于$ PYTHONPATH,因此我认为它必须在某个时候通过我的解释器,因为我的问题是特定于该变量$ CONFPATH的.

Once again and in both cases, it does work for $PYTHONPATH, so I suppose it must go through my interpreter at some point because my problem is specific to that variable $CONFPATH.

为什么我的python解释器中的os.system('command')与终端的命令输出不同?

推荐答案

我认为您期望有一个环境.事实是,每个进程都有自己的环境,通常是从其父进程继承的.不幸的是,我在您的摘要中看不到足够的信息来告诉您如何传递此特定值,但是我们可以仔细阅读它们,看看它们的实际含义.

I think you're expecting there to be one environment. The truth is, every process has its own environment, typically inherited from its parent process. Unfortunately I don't see enough information in your snippets to tell you how to pass this particular value, but we can go through them and see what they actually say.

echo $CONFPATH
/home/claramart/Datamart/Parameter

这显示了一个外壳命令 echo ,表明该外壳可以扩展参数 $ CONFPATH .但是,它不会显示它是来自shell还是环境变量.不过,后面的代码片段确实演示了您是否确实在其中设置了环境.

This shows a shell command echo demonstrating that the shell could expand the parameter $CONFPATH. It does not, however, show whether that was from a shell or environment variable. Later snippets do demonstrate you do have an environment within which it is set, though.

os.system('echo $CONFPATH')

0

这是一个Python函数调用,依次调用一个C库函数,该函数会生成一个新的shell并解释给定的命令.值得注意的是,这与您所运行的外壳不同;这是一个新的/bin/sh进程,该进程从进行调用的Python解释器继承环境.我们看到此shell命令成功(退出值0)并将CONFPATH扩展为空,表明在该命令中它为空或未设置Python解释器的环境.

Here is a Python function call, in turn calling a C library function, which causes a new shell to be spawned and interpret the given command. Notably this isn't the same shell as any you had running; it is a new /bin/sh process, which inherits environment from the Python interpreter the call was made in. We see that this shell command succeeded (exit value 0) and expanded CONFPATH to nothing, indicating that it was empty or unset in this Python interpreter's environment.

python3 -c 'import os; print(os.environ["CONFPATH"])'
/home/claramart/Datamart/Parameter

这是一个启动Python解释器的shell命令示例,其中的命令行使它解释了环境变量.它成功了,因为该变量是从您运行命令的外壳程序继承而来的.

Here is an example of a shell command starting a Python interpreter, with a command line causing it to print the environment variable. It succeeded, as the variable was inherited from the shell in which you ran the command.

os.system("""python3 -c 'import os; print(os.environ["CONFPATH"]'""")
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python3.5/os.py", line 725, in __getitem__
    raise KeyError(key) from None
KeyError: 'CONFPATH'
256

这里一个包裹着另一个;从Python解释器启动外壳程序以运行命令,该命令将启动另一个应该输出CONFPATH环境变量的Python解释器.该内部Python代码失败,但是,在其环境中找不到CONFPATH时引发了KeyError异常.这与仅显示一个空值的外壳行为相反.由于未捕获到异常,因此进行了追溯,并且Python外壳返回了错误代码,该错误代码又由子外壳返回,最后由我们的外部Python解释器打印为256.

Here one is wrapped in another; from a Python interpreter, a shell is started to run a command which starts another Python interpreter that is supposed to print the CONFPATH environment variable. This inner Python code fails, however, raising a KeyError exception on not finding CONFPATH in its environment. This is in contrast to the shell's behaviour which was to simply show an empty value. Since the exception was not caught, a traceback was printed and the Python shell returned an error code, in turn returned by the subshell, and finally printed by our outer Python interpreter as 256.

您已经显示了从两个不同的环境运行的命令:在其中设置CONFPATH的外壳程序,以及未设置CONFPATH的Python解释器. pstree ps f ps -H 可以帮助您可视化流程树以及环境的继承位置.请注意,该环境是从父进程复制而来的;在父母中更改它只会影响新的孩子,而不影响现有的孩子.

You have shown commands run from two distinct environments: a shell in which CONFPATH is set, and a Python interpreter in which it is not. pstree, ps f or ps -H might help you visualize the process tree and thus where the environment was inherited from. Note that the environment is copied from the parent process; changing it in a parent will only affect new children, not existing ones.

在Linux中,还可以在/proc文件系统中找到环境.例如, tr \\ 0 \\ n</proc/$$/environ 打印运行它的shell的环境(shell将$$扩展为它自己的进程ID).

In Linux it is also possible to find the environment in the /proc filesystem. For instance, tr \\0 \\n < /proc/$$/environ prints the environment of the shell it's run from (the shell expands $$ into its own process ID).

当您在不同的环境中运行事物时,这种区别变得尤为重要.例如,通过您的 .profile .bashrc 文件设置的任何内容都不会影响从 cron 运行的命令,并且不会影响系统启动脚本.大多数程序会直接离开环境,但有些程序会产生特定的例外情况,例如setuid程序会忽略LD_LIBRARY_PATH或 su env 重写环境.

This distinction becomes more important as you run things from different environments; for instance, anything set through your .profile or .bashrc files won't affect commands run from cron, and similarly with system startup scripts. Most programs leave the environment as is but some make specific exceptions, such as setuid programs ignoring LD_LIBRARY_PATH, or su and env rewriting the environment.

这篇关于os.system与命令行有何不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆