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

妖精的绣舞 提交于 2019-12-14 03:41:04

问题


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

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

source HOME/.bashrc

source is a bash built-in so I cannot just:

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 ?


回答1:


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

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.




回答2:


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 command does not execute command. it just stores the string "command" in the variable $1 and 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.

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.

source is 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.

see this answer for 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.

prepare a bash script to run your python script and then 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

add an alias to your .bashrc to source that script

alias add_alias='source modify_bash_aliases.sh'

now when you type add_alias some_alias in your bash prompt it will be replaced with source modify_bash_aliases.sh and then executed. since source is 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 source command will run inside your currently running bash session.

another way

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

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

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

now you can call the function like this: add_alias some_alias




回答3:


[[working solution]]

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()



回答4:


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

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.

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


来源:https://stackoverflow.com/questions/3661566/python-source-home-bashrc-with-os-system

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!