I like to put many of my environment variable definitions in the .profile script. If I am using a POSIX-compatible interactive shell like bash, I can use the source command to re-export the environment variables from .profile when it gets updated, without needing to open a new terminal window. Is there a way to do the same when I am using fish, which uses a different syntax for exporting variables? Can I tell fish to run a sh subproccess and reexport any variables it defines?

When I try doing the obvious sh .profile the environment variables apparently only get defined in the child sh process and don't get updated in the parent fish process.

edit: the shell code defining my variables is this one

CAML_LD_LIBRARY_PATH="/home/hugo/.opam/4.01.0/lib/stublibs"; export CAML_LD_LIBRARY_PATH;
PERL5LIB="/home/hugo/.opam/4.01.0/lib/perl5:"; export PERL5LIB;
OCAML_TOPLEVEL_PATH="/home/hugo/.opam/4.01.0/lib/toplevel"; export OCAML_TOPLEVEL_PATH;
MANPATH=":/home/hugo/.opam/4.01.0/man"; export MANPATH;
PATH="/home/hugo/.opam/4.01.0/bin:/home/hugo/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games"; export PATH;

Unfortunately, this code is automatically generated by another program, so the conversion to Fish must also be made using an automated process. I tried using the following sed script

sed 's/\(.*\)="\(.*\)".*/set -x \1 \'\2\';/'

which outputs the following Fish code

set -x CAML_LD_LIBRARY_PATH '/home/hugo/.opam/4.01.0/lib/stublibs';
set -x PERL5LIB '/home/hugo/.opam/4.01.0/lib/perl5:';
set -x OCAML_TOPLEVEL_PATH '/home/hugo/.opam/4.01.0/lib/toplevel';
set -x MANPATH ':/home/hugo/.opam/4.01.0/man';
set -x PATH '/home/hugo/.opam/4.01.0/bin:/home/hugo/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games';

Which I can run using eval and () substitution

eval (my-sed-script)

However, fish is complaining when I try to set PATH. I think it might be special-casing PATH and expecting an array instead of a single string.

set: Warning: path component /home/hugo/.opam/4.01.0/bin:/home/hugo/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games may not be valid in PATH.
set: No such file or directory
set: Did you mean 'set PATH $PATH /home/hugo/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games'?
  • No you cannot. A child process cannot alter the environment of its parent. Show the format of your .profile. We can probably translate it into valid fish syntax, the result can be evaled – glenn jackman Oct 14 '14 at 23:35
  • @glennjackman: aw, that sucks. I edited the question to add the extra information you asked for. Right now I still need to figure out how to set PATH in fish and how to integrate that into the sed script. – hugomg Oct 15 '14 at 0:35

Unlike bash, the fish PATH is an array of directories: http://fishshell.com/docs/current/index.html#variables

sed '/^PATH=/s/:/\' \'/g; s/\(.*\)="\(.*\)".*/set -x \1 \'\2\';/'

For sourcing a general sh script in fish, one option is the bass plugin, which can source a bash script's environment variables into fish.

If you have fisherman, you can install with fisher edc/bass, then do bass source <command>.

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.