bash 带有 os.system() 的 Python 'source HOME/.bashrc'

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3661566/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 22:35:39  来源:igfitidea点击:

Python 'source HOME/.bashrc' with os.system()

pythonbashos.system

提问by Andrei Ciobanu

I am writing a python script (Linux) that is adding some shell aliases(writes them to HOME/.bash_aliases).

我正在编写一个 python 脚本 (Linux),它添加了一些shell 别名(将它们写入HOME/.bash_aliases)。

In order to make an alias available immediately after it was written I should issue the following bash built-in:

为了在写入后立即使别名可用,我应该发出以下 bash 内置命令:

source HOME/.bashrc

sourceis a bash built-in so I cannot just:

source是内置的 bash,所以我不能只是:

os.system(source HOME/.bashrc)

If i try something like:

如果我尝试类似的事情:

os.system('/bin/bash -c source HOME/.bashrc')

...will freeze the script (just like is waiting for something).

...将冻结脚本(就像在等待某些东西一样)。

Any suggestions ?

有什么建议 ?

采纳答案by Daenyth

What you want is not possible. A program (your script) cannot modify the environment of the caller (the shell you run it from).

你想要的是不可能的。程序(你的脚本)不能修改调用者的环境(你运行它的 shell)。

Another approach which would allow you to do something close is to write it in terms of a bash function, which is run in the same process and can modify the caller. Note that sourcing during runtime can have possible negative side-effects depending on what the user has in their bashrc.

另一种允许你做一些接近的事情的方法是根据 bash 函数来编写它,它在同一进程中运行并且可以修改调用者。请注意,根据用户在其 bashrc 中拥有的内容,运行时期间的采购可能会产生负面影响。

回答by lesmana

what you are trying to do is impossible. or better: how you are trying to do it is impossible.

你想做什么是不可能的。或者更好:您尝试如何做到这一点是不可能的。

  1. your bash command is wrong. bash -s commanddoes not execute command. it just stores the string "command" in the variable $1and then drops you to the prompt. that is why the python script seems to freeze. what you meant to do is bash -c command.

  2. why do you source .bashrc? would it not be enough to just source .bash_aliases?

  3. even if you got your bash command right, the changes will only take effect in the bash session started from python. once that bash session is closed, and your python script is done, you are back at your original bash session. all changes in the bash session started from python is lost.

  1. 你的 bash 命令是错误的。bash -s command不执行command。它只是将字符串“command”存储在变量中$1,然后让您进入提示。这就是 python 脚本似乎冻结的原因。你的意思是bash -c command

  2. 你为什么要来源.bashrc?仅仅提供来源还不够.bash_aliases吗?

  3. 即使您的 bash 命令正确,更改也只会在从 python 启动的 bash 会话中生效。一旦该 bash 会话关闭,并且您的 python 脚本完成,您就回到了原始的 bash 会话。从 python 启动的 bash 会话中的所有更改都丢失了。

everytime you want to change something in the current bash session, you have to do it from inside the current bash session. most of the commands you run from bash (system commands, python scripts, even bash scripts) will spawn another process, and everything you do in that other process will not affect your first bash session.

每次您想在当前 bash 会话中更改某些内容时,都必须在当前 bash 会话中进行。您从 bash 运行的大多数命令(系统命令、python 脚本,甚至 bash 脚本)都会产生另一个进程,并且您在该进程中所做的一切都不会影响您的第一个 bash 会话。

sourceis a bash builtin which allows you to execute commands inside the currently running bash session, instead of spawning another process and running the commands there. defining a bash function is another way to execute commands inside the currently running bash session.

source是一个 bash 内置程序,它允许您在当前运行的 bash 会话中执行命令,而不是生成另一个进程并在那里运行命令。定义 bash 函数是在当前运行的 bash 会话中执行命令的另一种方式。

see this answerfor more information about sourcing and executing.

有关采购和执行的更多信息,请参阅此答案

what you can do to achieve what you want

你可以做什么来实现你想要的

modify your python script to just do the changes necessary to .bash_aliases.

修改你的 python 脚本,只对.bash_aliases.

prepare a bash script to run your python script and then source .bash_aliases.

准备一个 bash 脚本来运行你的 python 脚本,然后将.bash_aliases.

#i am a bash script, but you have to source me, do not execute me.
modify_bash_aliases.py "$@"
source ~/.bash_aliases

add an alias to your .bashrcto source that script

向您添加别名以.bashrc获取该脚本的来源

alias add_alias='source modify_bash_aliases.sh'

now when you type add_alias some_aliasin your bash prompt it will be replaced with source modify_bash_aliases.shand then executed. since sourceis a bash builtin, the commands inside the script will be executed inside the currently running bash session. the python script will still run in another process, but the subsequent sourcecommand will run inside your currently running bash session.

现在,当您输入add_alias some_aliasbash 提示符时,它将被替换为source modify_bash_aliases.sh然后执行。由于source是 bash 内置命令,脚本中的命令将在当前运行的 bash 会话中执行。python 脚本仍将在另一个进程中运行,但后续source命令将在您当前运行的 bash 会话中运行。

another way

其它的办法

modify your python script to just do the changes necessary to .bash_aliases.

修改你的 python 脚本,只对.bash_aliases.

prepare a bash function to run your python script and then source .bash_aliases.

准备一个 bash 函数来运行你的 python 脚本,然后将.bash_aliases.

add_alias() {
  modify_bash_aliases.py "$@"
  source ~/.bash_aliases      
}

now you can call the function like this: add_alias some_alias

现在你可以像这样调用函数: add_alias some_alias

回答by Cereal_Killer

[[working solution]]

[[工作解决方案]]

http://stackoverflow.com/questions/6856119/can-i-use-an-alias-to-execute-a-program-from-a-python-script

http://stackoverflow.com/questions/6856119/can-i-use-an-alias-to-execute-a-program-from-a-python-script

import subprocess
sp = subprocess.Popen(["/bin/bash", "-i", "-c", "nuke -x scriptpath"])
sp.communicate()

回答by Jim Bagwell

I had an interesting issue where I needed to source an RC file to get the correct output in my python script.

我有一个有趣的问题,我需要获取一个 RC 文件才能在我的 python 脚本中获得正确的输出。

I eventually used this inside my function to bring over the same variables from the bash file I needed to source. Be sure to have os imported.

我最终在我的函数中使用它来从我需要获取的 bash 文件中引入相同的变量。确保导入了 os。

with open('overcloudrc') as data:
    lines = data.readlines()

for line in lines:
    var = line.split(' ')[1].split('=')[0].strip()
    val = line.split(' ')[1].split('=')[1].strip()
    os.environ[var] = val