用os.system()执行Python 'source HOME/.bashrc'命令

13

我正在编写一个Python脚本(在Linux上),它会添加一些shell aliases(将它们写入HOME/.bash_aliases)。

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

source HOME/.bashrc

source 是 Bash 内置命令,因此我不能简单地执行以下操作:

os.system(source HOME/.bashrc)

如果我尝试这样做:
os.system('/bin/bash -c source HOME/.bashrc')

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

有什么建议吗?

4个回答

7
你想要的是不可能的。一个程序(你的脚本)不能修改调用者的环境(你从中运行它的shell)。
另一种方法是编写一个Bash函数,它在同一个进程中运行并可以修改调用者。请注意,在运行时进行源代码处理可能会产生负面影响,具体取决于用户在他们的bashrc中设置了什么。

感谢您的反馈。与此同时,我进行了一些研究,是的,您是正确的,我想要的并不完全可能。解决方法是编写一个bash脚本,并在必要时运行它。但是我认为,在运行服务器上已经运行“密集”脚本的情况下,在运行时修改环境可能是危险的。 - Andrei Ciobanu
@Andrei 我尝试使用Bash脚本来进行源代码,但是也没有成功。 - peacepassion

3
你想要做的是不可能的,或者更好地说,你尝试的方式是不可能的。
  1. 你的 bash 命令是错误的。 bash -s command 并不执行 command。它只是将字符串 "command" 存储在变量 $1 中,然后将你带到提示符。这就是为什么 Python 脚本似乎会冻结。你原本打算做的应该是 bash -c command
  2. 你为什么要 source .bashrc?仅 source .bash_aliases 不就够了吗?
  3. 即使你的 bash 命令正确,所做的更改也只会在从 Python 启动的 bash 会话中生效。一旦那个 bash 会话被关闭并且你的 Python 脚本完成后,你又回到了原来的 bash 会话。从 Python 启动的 bash 会话中的所有更改都会丢失。
每次想要更改当前 bash 会话中的内容时,你必须从当前 bash 会话内部进行更改。你在 bash 中运行的大多数命令(系统命令、Python 脚本,甚至是 bash 脚本)都会生成另一个进程,并且你在另一个进程中所做的任何事情都不会影响你的第一个 bash 会话。 source 是一个 bash 内置命令,它允许你在当前运行的 bash 会话内执行命令,而不是生成另一个进程并在那里运行命令。定义一个 bash 函数是另一种在当前运行的 bash 会话中执行命令的方式。
有关 source 和 execute 的更多信息,请参见 这个答案

如何达到你的目标

修改你的 Python 脚本,只对 .bash_aliases 做必要的更改。
准备一个 bash 脚本来运行你的 Python 脚本,然后 source .bash_aliases
#i am a bash script, but you have to source me, do not execute me.
modify_bash_aliases.py "$@"
source ~/.bash_aliases

在你的.bashrc中添加一个别名,以便引用该脚本。
alias add_alias='source modify_bash_aliases.sh'

现在,当你在bash提示符中输入add_alias some_alias时,它会被替换为source modify_bash_aliases.sh然后执行。因为source是bash内置的,所以脚本内部的命令将在当前运行的bash会话中执行。Python脚本仍将在另一个进程中运行,但随后的source命令将在当前正在运行的bash会话中运行。
另一种方法是修改你的Python脚本,只需对.bash_aliases做必要的更改。
准备一个bash函数来运行你的Python脚本,然后源.bash_aliases
add_alias() {
  modify_bash_aliases.py "$@"
  source ~/.bash_aliases      
}

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


0

我遇到了一个有趣的问题,我需要引用一个RC文件来获得我的Python脚本中正确的输出。

最终,我在我的函数中使用了这个方法,以便从我需要引用的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

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接