I have a bash script which cats a heredoc string, and I'm running it inside a fish shell and then piping it to a source call, like so:


  1 #!/usr/bin/env bash
  3 cat << EOS
  4   function bar
  5     echo 'Hello world'
  6   end
  7 EOS

From the fish shell:

richiethomas@richie ~/foo (master) [126]> ./baz | source
richiethomas@richie ~/foo (master)> bar

Hello world

As shown above, this results in the function bar being callable when I run ./baz | source.

However, I get an error when I change the implementation of the bar function to the following:

  1 #!/usr/bin/env bash
  3 cat << EOS
  4   function bar 
  5     set myVar 5 
  6     switch $myVar 
  7       case 4 
  8         echo '4' 
  9       case 5 
 10         echo '5' 
 11       case '*' 
 12         echo 'Not found' 
 13     end 
 14   end
 15 EOS

When I try to source this, I get the following error:

richiethomas@richie ~/foo (master) [0|1]> ./baz | source
- (line 1): Missing end to balance this function definition
  function bar
from sourcing file -
source: Error while reading file '<stdin>'

An equivalent function + switch statement works fine when I paste it directly in the fish shell:

richiethomas@richie ~/foo (master) [0|1]> function bar
                                              set myVar 5
                                              switch $myVar
                                                  case 4
                                                      echo 'it is 4!'
                                                  case 5
                                                      echo 'it is 5!'
                                                  case '*'
                                                      echo 'not found'

richiethomas@richie ~/foo (master)> bar

it is 5!

I have the same # of end statements in both the baz file and the code I copy/pasted into the shell, so I suspect the error statement is a red herring? If so, I don't know what the real error could be.

My goal is to be able to construct a fish function inside the heredoc string of a bash script, then source that bash script from a fish script so that I can call that function. Where did I go wrong here?

  • I don't understand your archtitecture. Are these bash scripts generated dynamically? What aren't these fish functions stored in ~/.config/fish/functions/? Commented Sep 11, 2022 at 22:58
  • These scripts are purely a learning exercise, not part of a permanent set of functions. So there shouldn't be a need to store them in a permanent config directory. Commented Sep 11, 2022 at 23:01

1 Answer 1


Variables ($myVar) get expanded in heredocs, unless you quote it:

cat << 'EOS'
# .....^...^

Ref 3.6.6 Here Documents

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .