4

My default shell is fish, because it's a lot nicer. But often when I run scripts, I get errors that seem to be from the bash script being processed by fish. I think this is because the script writer assumed that the default shell is bash, but I don't understand the mechanism.

For instance, the CrashPlan install.sh script starts with a bash shebang:

~/CrashPlan-install> head install.sh
#!/bin/bash

#############################################################
# Linux Client Installer Script
#############################################################

So when I run ./install.sh it should be processed by bash, right? The default terminal shell should be irrelevant. Yet, when my default shell is fish, running scripts like this causes fish to return errors, as if it's processing the script:

fish: Expected a command name, got token of type “Run job in background”. Did you mean
 “COMMAND; and COMMAND”? See the help section for the “and” builtin command by typing “help and”.
Standard input: sed -imod "s|Exec=.*|Exec=/usr/local/crashplan/bin/CrashPlanDesktop|" 
 /home/username/Desktop/CrashPlan.desktop && rm -rf /home/username/Desktop/CrashPlan.desktopmod 

Is this because of a misconfiguration of my computer or because the script is written in a non-portable way?

endolith
  • 7,507
  • 25
  • 84
  • 121

1 Answers1

6

So when I run ./install.sh it should be processed by bash, right?

Indeed. That's exactly what the shebang is for.

Troubleshooting

  • Save the following as test.sh and try to run it from fish.

    #!/bin/bash
    
    true && true
    

    It works on my computer, and it should on yours.

  • Check if the first line of install.sh contains only the characters #!/bin/bash.

    Invisible characters (such as a CR linebreak) could confuse fish.

  • Run

    /bin/bash --version
    

    to check that bash is actually bash and hasn't been accidentially replaced/modified over time.

install.sh

$SRC_USER is just a synonym the script creates for $SUDO_USER.

As a result, when the script is run with root privileges, the command

su ${SRC_USER} -c "sed -imod \"s|Exec=.*|Exec=${GUISCRIPT}|\" ${DESKTOP_LAUNCHER} && rm -rf ${DESKTOP_LAUNCHER}mod"

automatically uses the sudo user's default shell, which is fish.

To override this default, add the instruction -s /bin/bash to the su command.

Dennis
  • 48,917
  • 12
  • 130
  • 149
  • `./test.sh` runs fine, produces no errors, and a hex dump of test.sh and install.sh is identical for the first 13 bytes. And yes, it's `GNU bash, version 4.2.24(1)-release`. Something to do with the `Exec=` part of the install.sh script? – endolith Nov 16 '12 at 19:11
  • Maybe, but it's hard to tell out of context. Could you post `install.sh` here or, if it's too long, on Pastebin? – Dennis Nov 16 '12 at 19:16
  • http://pastebin.com/xAZM1BgF Oh no, now I see the "Exec" is part of a `.desktop` file that the script creates, not part of the script itself. – endolith Nov 16 '12 at 19:31
  • I honestly don't get it: fish can't handle any of the if commands, so why wait until the sed line to choke? What happens if you run `bash install.sh`? – Dennis Nov 16 '12 at 20:21
  • the same thing happened with `sudo install.sh` or `bash install.sh`. Something to do with `su ${SRC_USER}`? But root's default shell is bash. – endolith Nov 16 '12 at 20:32
  • I think you got it. `su` executes the command using `SRC_USER`'s shell, which, if I got it right, is precisely not `root`. Try replacing `su` with `su -s /bin/bash`. – Dennis Nov 16 '12 at 20:39
  • 2
    Yes, I think it's the `su` command. I've created a user `fishy` with fish as its default shell. From bash, `su fishy "true && true"` results in an error. `su fishy -s /bin/bash -c "true && true"` works fine. – Dennis Nov 16 '12 at 20:46
  • awesome, that seems to fix it. can you put that in your answer before I accept it? – endolith Nov 16 '12 at 20:52
  • Glad for it. I've updated my answer. – Dennis Nov 16 '12 at 20:57