Add a relative path to $PATH on fish startup
-
20-12-2020 - |
Pergunta
I want to add ./bin directory (which is relative to current shell directory) to $PATH on fish startup. Note that fish
is a shell.
echo $PATH
set PATH ./bin $PATH
echo $PATH
If I place these lines inside ~/.config/fish/config.fish
the shell will echo the same collection of paths. Absolute paths are added properly.
If I open the shell and type the same set PATH ./bin $PATH
inside some directory containing bin
it is added successfully. However when there is no bin
inside current directory it shows me an error.
set: Could not add component ./bin to PATH.
set: Value too large to be stored in data type
I'm running fish 1.23.1 on OS X Lion.
Solução 5
It seems like fish
won't add a non-existing directory path to PATH. That applies to relative paths too. But if you create bin
directory in your home directory set PATH ./bin $PATH
will work properly on each startup since it is executed from home. This is kind of a hack though.
Outras dicas
The best way I have found to persistently add a path to your $PATH
is
set -U fish_user_paths $fish_user_paths ~/path/name
This prepends to $PATH
. And since it's persistent, the path stays in $PATH
on shell restarts.
It's more efficient than putting a command in your config.fish
to modify your $PATH
, because it only runs once compared to running on every shell restart.
The variable fish_user_paths
is intended to be set by the user1, as stated by ridiculousfish, the maintainer of fish.
Consider creating a fish function for convenience: 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
And use it as:
$ add_to_path foo bar # Adds foo/ and bar/ to your PATH
Notes
On that page the author gives the example
set -U fish_user_paths ~/bin
. This overwritesfish_user_paths
with a single value of~/bin
. To avoid losing existing paths set infish_user_paths
, be sure to include$fish_user_paths
in addition to any new paths being added (as seen in my answer).My dotfiles contain a slightly more advanced version that skips adding duplicates https://github.com/dideler/dotfiles/blob/master/.config/fish/functions/add_to_user_path.fish
I'd never heard of fish
before this. I just installed it so I could try it out (and deleted a few paragraphs I had written here before realizing that fish
is a shell).
It looks like set PATH dir-name $PATH
is the right syntax to prepend a directory to $PATH
.
But adding a relative directory name to $PATH
is almost certainly a bad idea, and your shell is doing you a favor by warning you when the directory doesn't exist. (fish
is designed to be user-friendly.)
Use an absolute path instead:
set PATH $PWD/bin $PATH
and first check whether $PWD/bin
exists, printing an error message if it doesn't.
As for the "set: Value too large to be stored in data type
" message, could you be adding the directory to your $PATH
multiple times? There should be some way to check whether a directory is already in $PATH
before adding it.
I think the answer is that using set -U
is a red herring. Instead, add the following to ~/.config/fish/config.fish
:
if status --is-interactive
set PATH $PATH ~/.local/bin;
end
direnv http://direnv.net/ is a good utility to help with what you're doing.
Generally, prepending $PATH with ./bin is insecure, as anyone with write-access to a shared directory could hide malicious code in e.g. ./bin/ls. That code would execute when you run ls in the shared directory.
direnv does not solve this problem (it works based on .envrc files, but anyone could be placing those), but at the very least it makes you aware when you cd into a directory that $PATH is getting modified:
$ cd my_project
direnv: loading .envrc
direnv export: ~PATH