在鱼启动时添加到 $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 the fish_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 的相对路径的主要内容,如果未能解决你的问题,请参考以下文章

Test-Path 是不是接受相对路径?

从绝对路径到相对路径

webpack无法使用相对路径解决办法

模块的绝对导入相对导入

当 CWD 发生变化时,如何在 Python 模块中使用相对路径?

python 相对路径和绝对路径的区别