我可以根据我的 cwd 动态更改我的 PATH 吗?

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,但对通用解决方案感兴趣。

pyr*_*sty 3

介绍

如果我理解正确的话,您想要添加或其任何祖先"$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,在每个祖先中查找目标目录并将找到的任何目录添加到路径中。

脚本

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)