Why doesn’t set -x work within eval within a function in fish

fish

I ran into an issue trying to dynamically set some variables based on output of a program, in a fish function.

I narrowed my issues down to a MWE:

function example
    eval (echo 'set -x FOO 1;')
end

calling:

>example
>echo $FOO

results in no output — ie the FOO environment variable has not been set.
How should I have done this?

Best Answer

The same thing happens in a simpler form:

function trythis
     set -x foo bar
end

If you now run trythis and echo $foo, it is not set either. That's because fish's -x by itself doesn't change the scope of the variable, which is by default local to the function unless it exists globally or universally already.

Try:

  eval (echo 'set -gx FOO 1;') 

Where the g is for global. This makes the variable work like a normal POSIX exported value. It's interesting that it works the same way with eval as it would with just plain set; if you use that line sans g straight on the command line, $FOO is set, so eval and process substitution () have not introduced a new scope or subshell, and when executed that way within a function, the scope of the function applies.

Related Question