Pip*_*ipo 5 linux bash shell path environment-variables
我想$PATH
根据我当前的工作目录更改我的环境变量。
假设我在/foo/bar/baz
,我有目录/foo/node_modules/.bin
和/foo/bar/baz/node_modules/.bin
. 我想将所有可能的./node_modules/.bin
递归添加到$PATH
.
但是当我cd
进入不同的目录(如/foo/bar
)时,我希望$PATH
恢复我原来的、干净的,然后再次开始./node_modules/.bin
递归查找。
(我想从 npm 的问题跟踪器中解决我自己的问题:我们也可以将本地安装的包添加到 PATH 中吗?)
注意:我使用的是 Mac,但对通用解决方案感兴趣。
如果我理解正确的话,您想要添加或其任何祖先"$X/node_modules/.bin"
所在的任何目录。$X
$PWD
本文末尾的脚本应该给出您想要的行为。您需要在每个需要的会话中获取它。如果您将文件命名为augment_path.sh
,那么将此行添加到您的文件中.bashrc
就足够了:
source augment_path.sh
Run Code Online (Sandbox Code Playgroud)
我认为加里约翰的基本方法是正确的,但他正在搜索所有后代而不是所有祖先。
该$PROMPT_COMMAND
变量允许您指定每次显示提示时要执行的命令。我添加了一个变量以允许恢复$PROMPT_COMMAND_OLD
原始内容$PROMPT_COMMAND
这可能没有必要,但为了良好的形式,我添加了一个$LAST_WD
变量并进行测试,以避免在目录未更改时重新计算路径。LAST_WD
如果您愿意,可以删除包含的所有三行。
该augment_path
函数从向上扫描$PWD
,在每个祖先中查找目标目录并将找到的任何目录添加到路径中。
它们按顺序放置在路径中,因此如果有任何冲突,将优先考虑最深的目录。我认为这是期望的行为。如果没有,请更改
PATH_ADDITION="$PATH_ADDITION:$resolved_target"
Run Code Online (Sandbox Code Playgroud)
到
PATH_ADDITION="$resolved_target:$PATH_ADDITION"
Run Code Online (Sandbox Code Playgroud)但是,这些目录都将优先于路径的其余部分。如果您希望路径的其余部分优先,请更改:
PATH="$PATH_ADDITION:$RAW_PATH"
Run Code Online (Sandbox Code Playgroud)
到
PATH="$RAW_PATH:$PATH_ADDITION"
Run Code Online (Sandbox Code Playgroud)RAW_PATH="$PATH"
LAST_WD=`pwd`
augment_path() {
target="node_modules/.bin"
if [ "$PWD" = "$LAST_WD" ]; then return 0; fi;
PATH_ADDITION=""
scandir="$PWD"
until [ "$scandir" = "" ]; do
resolved_target="$scandir"/"$target"
if [ -d "$resolved_target" ]; then
PATH_ADDITION="$PATH_ADDITION:$resolved_target"
fi
scandir="${scandir%/*}"
done
PATH="$PATH_ADDITION:$RAW_PATH"
LAST_WD=`pwd`
}
PROMPT_COMMAND_OLD="${PROMPT_COMMAND%; augment_path}"
PROMPT_COMMAND="$PROMPT_COMMAND_OLD; augment_path"
Run Code Online (Sandbox Code Playgroud)