In bash I can do:

foo() { echo bar; }
export -f foo
perl -e 'system "bash -c foo"'

I can also access the function definition:

perl -e 'print "foo".$ENV{"BASH_FUNC_foo%%"}'

How do I do the same in fish?


With this I can get the function definition:

functions -n | perl -pe 's/,/\n/g' | while read d; functions $d; end

If I can put that in an enviroment variable accessible from Perl, I ought to be able to execute that before executing the command. So similar to:

setenv funcdefs (functions -n | perl -pe 's/,/\n/g' | while read d; functions $d; end)
perl -e 'system($ENV{"funcdefs"},"foo")'

But it seems setting funcdefs ignores the newlines: $ENV{"funcdefs"} is one horribly long line.

The odd part is that it seems fish does support environment variables containing newlines:

setenv newline 'foo
echo "$newline"

Can I encourage fish to put the output from the command into a variable, but keeping the newlines?

  • Variable contains newline worked fine for me in fish 2.1.0. fish disable word splitting by default.
    – cuonglm
    May 20, 2015 at 11:05
  • @cuonglm I tested with 2.1.1. This still does not work: setenv quux (echo foo;echo bar); echo "$quux". It works beautifully in Bash: quux=$(echo foo;echo bar); echo "$quux"
    – Ole Tange
    May 20, 2015 at 11:48
  • I'm not sure about that. I tried enter newline literally, set var 'foo\nbar'
    – cuonglm
    May 20, 2015 at 12:56

2 Answers 2


In fish, you can use funcsave to save function definition across fish session:

$ function qwerty
    echo qwerty
$ funcsave qwerty
$ fish -c qwerty
$ perl -e 'system "fish -c qwerty"'
  • Assume it is a function that I will never use again, can I avoid saving it?
    – Ole Tange
    May 20, 2015 at 8:59
  • @OleTange: AFAIK, you can't. You can use functions -e funcname to erase the function after using it.
    – cuonglm
    May 20, 2015 at 9:03
  • Would that not violate the first design principle for fish? fishshell.com/docs/current/design.html
    – Ole Tange
    May 20, 2015 at 10:59
  • @OleTange: I think no. funcsave can do job that export -f can do and it more powerful than that since when it can work across all fish session. It can be considered the same as what you do in .bashrc
    – cuonglm
    May 20, 2015 at 11:12
  • I respectfully disagree that forcing a function to be globally visible is more powerful than being able to keep it locally visible: I often create a throw-away function called doit. If I create a function in two different windows I do not want one definition to overwrite the other.
    – Ole Tange
    May 20, 2015 at 13:51

Ugly as hell, but works:

function foo
  echo bar;

setenv funcdefs (functions -n | perl -pe 's/,/\n/g' | while read d; functions $d; end|perl -pe 's/\n/\001/')
perl -e '$ENV{"funcdefs"}=~s/\001/\n/g;system ("fish", "-c", $ENV{funcdefs}."foo")'

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.