I'm currently migrating from bash configs over to fish and got stuck translating my over bash exports. It seems there's three ways to do it in Fish that get the job done but I can't tell which one I should use, or if they have side effects I am unaware of

set -g VAR value
set -x VAR value
set -xg VAR value

Surely they do not all do the same thing. Can someone explain what the differences are and in which situations each is appropriate, please?

  • Typing set -h will show the meanings under scope options. – AFH May 27 at 21:52
up vote 3 down vote accepted

No, they do not all do the same thing. The -x flag is orthogonal to the -g, -l, and -u flags. The former simply sets the export attribute on the var. The latter three set the scope of the var. You can have a global, unexported, VAR and inside a function do set -lx VAR value to create a locally scoped instance that is exported. When control returns from the function the global scope VAR pops back into existence and it won't be exported.

If you're using a recent version (2.7, maybe 2.6) you can do set --show VAR to display the values in all three scopes and whether or not each one is exported.

  • Sorry, what does it mean for a variable to be exported? – 11th Hour Worker May 28 at 1:24
  • An exported variable is visible to commands run by your fish shell. Do set -g NOT_EXPORTED abc; set -gx EXPORTED def; env | grep EXPORTED. Note that env is an external command that shows the exported variables it inherited. It should show that only the var created via set -gx is present. – Kurtis Rader May 28 at 4:02
  • Thanks for explaining Kurtis. That's what I figured, but now I am confused why I can see the environment variables I set inside my config.fish using set -g? – 11th Hour Worker May 29 at 0:26
  • If the variable is already exported then set -g retains the exported attribute. So if, for example, you're doing something like set -g PATH /dir1 /dir2 $PATH it will remain exported because it was in the exported environment when fish started running. – Kurtis Rader May 29 at 2:27
  • I did previously define my variable with -x before for testing and didn't delete that line, expecting it to get overwritten in my next declaration of my variable. Thank you so much Kurtis! It all makes sense to me now :) – 11th Hour Worker May 29 at 22:42

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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