| title | 如何将目录添加到你的 PATH |
|---|---|
| date | 2025-02-13 12:27:56 UTC |
| authorURL | |
| originalURL | https://jvns.ca/blog/2025/02/13/how-to-add-a-directory-to-your-path/ |
| translator | |
| reviewer |
• [terminal][1] •
今天我和一个朋友讨论如何将目录添加到你的 PATH。对于我这种长期使用终端的人来说,这感觉很"显而易见",但当我搜索如何做这件事的说明时,我实际上找不到解释所有步骤的内容——很多只是说"将这个添加到~/.bashrc",但如果你不使用 bash 怎么办?如果你的 bash 配置实际上在不同的文件中怎么办?而且你应该如何确定要添加哪个目录呢?
所以我想尝试写下一些更完整的指导,并提及我多年来遇到的一些陷阱。
以下是目录:
如果你不确定你使用的是什么 shell,这里有一种方法可以找出来。运行这个:
ps -p $$ -o pid,comm=- 如果你使用的是 bash,它会打印出
97295 bash - 如果你使用的是 zsh,它会打印出
97295 zsh - 如果你使用的是 fish,它会打印出一个错误,比如 "In fish, please use $fish_pid"(
$$在 fish 中不是有效的语法,但无论如何错误消息告诉你你正在使用 fish,这你可能已经知道了)
另外,bash 是 Linux 的默认 shell,而 zsh 是 Mac OS 的默认 shell(截至 2024 年)。在这些指导中,我只会涵盖 bash、zsh 和 fish。
- 在 zsh 中,它可能是
~/.zshrc - 在 bash 中,它可能是
~/.bashrc,但这很复杂,请参阅下一节中的说明 - 在 fish 中,它可能是
~/.config/fish/config.fish(如果你想 100% 确定,可以运行echo $__fish_config_dir)
Bash 有三个可能的配置文件:~/.bashrc、~/.bash_profile 和 ~/.profile。
如果你不确定你的系统设置使用哪一个,我建议通过这种方式测试:
- 在你的
~/.bashrc中添加echo hi there - 重启你的终端
- 如果你看到 "hi there",这意味着
~/.bashrc正在被使用!太好了! - 否则,删除它并尝试对
~/.bash_profile做同样的事情 - 如果前两个选项不起作用,你也可以尝试
~/.profile。
(有很多复杂的流程图解释了 bash 如何决定使用哪个配置文件,但在我看来,没有必要去内化它们,直接测试是确定的最快方法)
假设你正在尝试安装并运行一个名为 http-server 的程序,但它不起作用,像这样:
$ npm install -g http-server
$ http-server
bash: http-server: command not found
你如何找到 http-server 在哪个目录中?老实说,一般来说这并不容易——通常答案是"取决于 npm 的配置方式"。一些想法:
- 通常在设置新的安装程序(如
cargo、npm、homebrew等)时,当你首次设置它时,它会打印出一些关于如何更新你的 PATH 的指导。所以如果你注意的话,你可以在那时获得指导。 - 有时安装程序会自动更新你的 shell 配置文件以更新你的
PATH - 有时只是谷歌搜索"npm 在哪里安装东西?"就会找到答案
- 一些工具有一个子命令,告诉你它们配置安装东西的位置,比如:
- Node/npm:
npm config get prefix(然后附加/bin/) - Go:
go env GOPATH(然后附加/bin/) - asdf:
asdf info | grep ASDF_DIR(然后附加/bin/和/shims/)
- Node/npm:
一旦你找到了一个你认为可能是正确的目录,确保它确实是正确的!例如,我发现在我的机器上,http-server 在 ~/.npm-global/bin 中。我可以通过尝试在该目录中运行程序 http-server 来确保它是正确的目录,像这样:
$ ~/.npm-global/bin/http-server
Starting up http-server, serving ./public它工作了!现在你知道你需要添加到 PATH 的目录是什么,让我们进入下一步!
现在我们有了需要的 2 个关键信息:
- 你试图添加到 PATH 的目录(如
~/.npm-global/bin/) - 你的 shell 配置在哪里(如
~/.bashrc、~/.zshrc或~/.config/fish/config.fish)
现在你需要添加的内容取决于你的 shell:
bash 指导:
打开你的 shell 配置文件,添加一行像这样的内容:
export PATH=$PATH:~/.npm-global/bin/(显然,用你实际尝试添加的目录替换 ~/.npm-global/bin)
zsh 指令:
你可以做与 bash 相同的事情,但 zsh 也有一些稍微更高级的语法,如果你喜欢的话:
path=(
$path
~/.npm-global/bin
)fish 指令:
在 fish 中,语法不同:
set PATH $PATH ~/.npm-global/bin(在 fish 中你也可以使用 fish_add_path,关于这个的一些说明在下面)
现在,一个非常重要的步骤:如果你不重启 shell,更新 shell 配置不会生效!
有两种方法可以做到这一点:
- 打开一个新的终端(或终端标签),也许关闭旧的以避免混淆
- 运行
bash启动一个新的 shell(如果你使用的是 zsh,则运行zsh,如果你使用的是 fish,则运行fish)
我发现这两种方法通常都可以正常工作。
你应该完成了!尝试运行你想运行的程序,希望它现在能工作。
如果不行,这里有一些你可能遇到的问题:
如果运行了错误版本的程序,你可能需要将目录添加到 PATH 的_开头_而不是结尾。
例如,在我的系统上,我安装了两个版本的 python3,我可以通过运行 which -a 看到:
$ which -a python3
/usr/bin/python3
/opt/homebrew/bin/python3你的 shell 将使用的是列出的第一个。
如果你想使用 Homebrew 版本,你需要将该目录(/opt/homebrew/bin)添加到 PATH 的开头,在你的 shell 配置文件中放入这个(它是 /opt/homebrew/bin/:$PATH 而不是通常的 $PATH:/opt/homebrew/bin/)
export PATH=/opt/homebrew/bin/:$PATH或者在 fish 中:
set PATH ~/.cargo/bin $PATH所有这些指导只有在你从你的 shell 运行程序时才有效。如果你从 IDE、GUI、cron 作业或其他方式运行程序,你需要以不同的方式将目录添加到你的 PATH,具体细节可能取决于情况。
在 cron 作业中
一些选项:
- 使用你正在运行的程序的完整路径,如
/home/bork/bin/my-program - 将你想要的完整 PATH 作为 crontab 的第一行(类似于 PATH=/bin:/usr/bin:/usr/local/bin:……)。你可以通过运行
echo "PATH=$PATH"获取你在 shell 中使用的完整 PATH。
我老实说不确定如何在 IDE/GUI 中处理它,因为我很久没有遇到这种情况了,如果有人指点我正确的方向,我会在这里添加指导。
如果你编辑你的 path 并通过运行 bash(或 zsh,或 fish)启动一个新的 shell,你通常会得到重复的 PATH 条目,因为每次你启动 shell 时,shell 都会继续向你的 PATH 添加新东西。
就我个人而言,我认为我没有遇到过这种重复会破坏任何东西的情况,但如果你试图理解 PATH 的内容,重复可能会使调试 PATH 发生的事情变得更加困难。
一些处理方法:
- 如果你正在调试你的
PATH,打开一个新的终端来做,这样你就会得到一个"新鲜"的状态。这应该避免重复。 - 在你的 shell 配置的末尾去重你的
PATH(例如在 zsh 中,显然你可以用typeset -U path做到这一点) - 添加目录时检查它是否已经在你的
PATH中(例如在 fish 中,我相信你可以用fish_add_path --path /some/directory做到这一点)
如何去重你的 PATH 是特定于 shell 的,并且并不总是有内置的方法来做到这一点,所以你需要查找如何在你的 shell 中完成它。
这里有一个在 bash 或 zsh 中容易陷入的情况:
- 运行一个命令(它失败了)
- 更新你的
PATH - 运行
bash重新加载你的配置 - 按几次向上箭头重新运行失败的命令(或打开一个新的终端)
- 失败的命令不在你的历史记录中!为什么?
这是因为在 bash 中,默认情况下,历史记录直到你退出 shell 才会保存。
一些修复选项:
- 不要运行
bash重新加载你的配置,而是运行source ~/.bashrc(或在 zsh 中运行source ~/.zshrc)。这将在你当前会话中重新加载配置。 - 配置你的 shell 持续保存你的历史记录,而不是只在 shell 退出时保存历史记录。(如何做到这一点取决于你是使用 bash 还是 zsh,zsh 中的历史选项有点复杂,我不太确定最好的方法是什么)
当你第一次安装 cargo(Rust 的安装程序)时,它给你这些关于如何设置 PATH 的指导,这些指导根本没有提到特定的目录。
This is usually done by running one of the following (note the leading DOT):
. "$HOME/.cargo/env" # For sh/bash/zsh/ash/dash/pdksh
source "$HOME/.cargo/env.fish" # For fish这个想法是你将该行添加到你的 shell 配置中,他们的脚本会自动为你设置 PATH(可能还有其他东西)。
这是相当常见的(例如 Homebrew 建议你执行 brew shellenv),有两种方法可以处理这个:
- 只做工具建议的事情(比如将
. "$HOME/.cargo/env"添加到你的 shell 配置中) - 找出他们告诉你运行的脚本会将哪些目录添加到你的 PATH 中,然后手动添加这些目录。以下是我的做法:
- 在我的 shell 中运行
. "$HOME/.cargo/env"(如果使用 fish,则运行 fish 版本) - 运行
echo "$PATH" | tr ':' '\n' | grep cargo来确定它添加了哪些目录 - 看到它说
/Users/bork/.cargo/bin并将其缩短为~/.cargo/bin - 将目录
~/.cargo/bin添加到 PATH(使用本文中的指导)
- 在我的 shell 中运行
我认为按照工具建议做没有什么问题(它可能是"最好的方法"!),但个人而言,我通常使用第二种方法,因为我更喜欢确切地知道我正在更改什么配置。
fish 有一个方便的函数叫做 fish_add_path,你可以运行它来将目录添加到你的 PATH,像这样:
fish_add_path /some/directory这很酷(这是一个如此简单的命令!)但我已经停止使用它,原因有几个:
- 有时
fish_add_path会更新未来每个会话的PATH(使用"通用变量"),有时它只会更新当前会话的PATH,我很难分辨它会做哪一个。理论上文档解释了这一点,但我无法理解它们。 - 如果你几周或几个月后需要从你的
PATH中_移除_目录,因为也许你犯了一个错误,这有点难做到(不过在这个 github issue 的评论中有指导)。
希望这能帮助一些人。如果你在将目录添加到 PATH 时遇到了其他主要陷阱,或者你对这篇文章有疑问,请让我知道(在 Mastodon 或 Bluesky 上)!