在鱼启动时添加到 $PATH 的相对路径
Posted
技术标签:
【中文标题】在鱼启动时添加到 $PATH 的相对路径【英文标题】:Add a relative path to $PATH on fish startup 【发布时间】:2011-10-27 04:51:18 【问题描述】:我想在 fish 启动时将 ./bin 目录(相对于当前 shell 目录)添加到 $PATH。请注意,fish
是一个外壳。
echo $PATH
set PATH ./bin $PATH
echo $PATH
如果我将这些行放在~/.config/fish/config.fish
中,shell 将回显相同的路径集合。绝对路径已正确添加。
如果我打开外壳并在包含bin
的某个目录中键入相同的set PATH ./bin $PATH
,则添加成功。但是,当当前目录中没有 bin
时,它会显示一个错误。
set: Could not add component ./bin to PATH.
set: Value too large to be stored in data type
我在 OS X Lion 上运行 fish 1.23.1。
【问题讨论】:
请注明底层操作系统(Linux or Windows or ??),以及shell系统(csh, ksh, bash, powershell, ???)祝您好运。fish
是一个外壳;这是the web site。
抱歉不清楚我使用的是什么外壳。
对于尝试设置 Homebrew / brew 软件包路径的 OS X 用户,我成功使用:set PATH /usr/local/bin $PATH
【参考方案1】:
我发现持续添加路径到您的$PATH
的最佳方法是
set -U fish_user_paths $fish_user_paths ~/path/name
这前置到$PATH
。并且由于它是持久的,因此在 shell 重新启动时,路径将保持在 $PATH
。
这比在你的config.fish
中输入一个命令来修改你的$PATH
更有效,因为它只运行一次,而不是在每次 shell 重启时运行。
变量fish_user_paths
is intended to be set by the user1,如fish的维护者ridiculousfish所述。
为方便起见,考虑创建一个鱼函数:2
# ~/.config/fish/functions/add_to_path.fish
function add_to_path --description 'Persistently prepends paths to your PATH'
set --universal fish_user_paths $fish_user_paths $argv
end
并将其用作:
$ add_to_path foo bar # Adds foo/ and bar/ to your PATH
注意事项
在该页面上,作者给出了示例set -U fish_user_paths ~/bin
。这将使用单个值 ~/bin
覆盖 fish_user_paths
。为避免丢失在fish_user_paths
中设置的现有路径,请务必在添加任何新路径之外包含$fish_user_paths
(如我的回答所示)。
我的点文件包含一个稍微高级一点的版本,它会跳过添加重复项https://github.com/dideler/dotfiles/blob/master/.config/fish/functions/add_to_user_path.fish
【讨论】:
更多细节,在这里讨论:github.com/fish-shell/fish-shell/issues/527 PATH 应该使用 -x 标志吗? @YichuanWang 应该不需要因为that's already done in thefish_user_path
handler【参考方案2】:
在此之前我从未听说过fish
。我刚刚安装了它,所以我可以尝试一下(并删除了我在这里写的几段,然后才意识到fish
是一个shell)。
看起来set PATH dir-name $PATH
是将目录添加到$PATH
的正确语法。
但是向$PATH
添加一个相对 目录名称几乎肯定是个坏主意,而且当目录不存在时,您的shell 会通过警告您来帮您一个忙。 (fish
设计为用户友好型。)
改用绝对路径:
set PATH $PWD/bin $PATH
首先检查$PWD/bin
是否存在,如果不存在则打印错误信息。
至于“set: Value too large to be stored in data type
”消息,您能否多次将该目录添加到您的$PATH
?应该有一些方法可以在添加之前检查一个目录是否已经在$PATH
中。
【讨论】:
但我真的希望./bin
在我的PATH 中,这样如果我在某个目录中cd
我可以在其./bin
子目录中调用任何可执行文件,而无需预先添加bin/
。 Zsh 允许我这样做。 $PWD/bin 将被设置一次并且不会相对于当前目录。
我会说这是一个坏主意,因为在您的$PATH
中包含.
是一个坏主意。假设您将cd
转换为/tmp/bad
,并且有人创建了一个运行rm -rf $HOME
的/tmp/bad/bin/ls
。如果我知道./bin
中有一个我想要执行的命令,我可以输入bin/whatever
;如果我不这样做,我可能不想执行它。但是如果你坚持,看起来fish
只在你运行set
命令时检查目录是否存在。设置$PATH
时,请确保您位于具有./bin
子目录的目录中;当您cd
到其他目录时,它会留在那里。【参考方案3】:
我认为答案是使用set -U
是一个红鲱鱼。相反,将以下内容添加到~/.config/fish/config.fish
:
if status --is-interactive
set PATH $PATH ~/.local/bin;
end
【讨论】:
抱歉,这可能无法回答最初的问题,但我会把它留给其他寻求提示的人!【参考方案4】:direnv http://direnv.net/ 是一个很好的实用程序,可以帮助您完成正在做的事情。
一般来说,在 $PATH 前面加上 ./bin 是不安全的,因为任何对共享目录具有写访问权限的人都可以隐藏恶意代码,例如./bin/ls.当您在共享目录中运行 ls 时,该代码将执行。
direnv 不能解决这个问题(它基于 .envrc 文件工作,但任何人都可以放置这些文件),但至少当你 cd 进入 $PATH 正在修改的目录时,它会让你知道:
$ cd my_project
direnv: loading .envrc
direnv export: ~PATH
【讨论】:
为什么投反对票? Direv 似乎是解决该问题的有用工具,而且提到安全隐患是这里大多数人没有想到的。 较新版本的 direnv 实际上通过要求用户将允许的.envrc
文件列入白名单来解决此攻击向量。每当遇到新的.envrc
文件时,direnv 将不允许它执行,直到用户运行direnv allow
或(direnv edit
并保存文件)。【参考方案5】:
似乎fish
不会将不存在的目录路径添加到 PATH。这也适用于相对路径。但是如果你在你的主目录中创建bin
目录set PATH ./bin $PATH
将在每次启动时正常工作,因为它是从家里执行的。不过,这有点像 hack。
【讨论】:
pushd ~ ; set PATH ./bin $PATH ; popd
(不过,我不认为这是一个好主意。)【参考方案6】:
就个人而言,我认为将.
添加到$PATH
的风险很小,只要它是最后一项,因为流氓ls
(或其他)在在/usr/bin/ls
之前将找不到 CWD。p>
我将此添加到我的config.fish
:
contains '.' $PATH; or set --export PATH $PATH .
你可以做类似的添加./bin
,再次在最后位置:
contains './bin'; or set --export PATH $PATH ./bin
这里发生了两件事:
-
这是直接设置
$PATH
,就像其他shell一样。这不会在 shell 中持续存在。
这会检查它是否已经在$PATH
中,这样子shell 就不会变得更长,$PATH
中的冗余条目
【讨论】:
以上是关于在鱼启动时添加到 $PATH 的相对路径的主要内容,如果未能解决你的问题,请参考以下文章