![Bash,环境等效](https://linux22.com/image/930116/Bash%EF%BC%8C%E7%8E%AF%E5%A2%83%E7%AD%89%E6%95%88.png)
假设我的 ~/.bashrc 中有以下导出
export MODE=vanilla
export PATH=/opt/bin/:/usr/bin/
我家里还有两部剧本
cat ~/setup_foo.sh
export MODE=foo
export PI_NUMBER=4
export PATH=/opt/bin/tool_foo/:$PATH
cat ~/setup_boo.sh
export MODE=boo
export PI_NUMBER=3
export PATH=/opt/bin/tool_boo:$PATH
我想要的功能:
$ echo $MODE
vanilla
echo $PATH
/opt/bin/:/usr/bin/
$ <<activate_foo>>
echo $MODE
foo
echo $PATH
/opt/bin/tool_foo/:/opt/bin/:/usr/bin/
$ <<activate_boo>>
echo $MODE
boo
echo $PATH
/opt/bin/tool_boo:/opt/bin/:/usr/bin/ --- NOTE, NO FOO HERE PRESERVED!
$ <<back_to_normal>>
echo $MODE
vanialla
echo $PATH
/opt/bin/:/usr/bin/ --- NO FOO AND BOO HERE!
我应该使用什么样的工具、包、bash 来代替<<伪命令>>?
如果我只是调用 ~/.setup_foo.sh,它将覆盖变量,但不会清理 PATH
答案1
可能最简单的方法是启动一个新的 bash shell 并获取安装文件,然后退出 shell 以返回到之前的环境。例如:
$ printenv grep '[bf]oo'
$ bash --rcfile setup_foo.sh
$ printenv | grep '[bf]oo'
MODE=foo
PATH=/opt/bin/tool_foo/:/home/steeldriver/bin:/home/steeldriver/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
$ exit
exit
$ printenv grep '[bf]oo'
$ bash --rcfile setup_boo.sh
$ printenv | grep '[bf]oo'
MODE=boo
PATH=/opt/bin/tool_boo:/home/steeldriver/bin:/home/steeldriver/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
$ exit
exit
$ printenv grep '[bf]oo'
答案2
通过先删除旧条目,可以防止它们多次出现。
#!/bin/bash
NEW_PATH=/opt/bin
PATH=$NEW_PATH:${PATH//$NEW_PATH:/}
echo $PATH
# And to remove your entry completely.
PATH=${PATH//$NEW_PATH:/}
echo $PATH
另一个示例使用 extglob 列表一次处理多个路径。
#!/bin/bash
shopt -s extglob
FOO_PATH=/opt/foo
BAR_PATH=/opt/bar
PATH=$FOO_PATH:$BAR_PATH:${PATH//@($FOO_PATH|$BAR_PATH):/}