9

On an Ubuntu ($ uname -a : Linux kumanaku 4.15.0-43-generic #46-Ubuntu SMP Thu Dec 6 14:45:28 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux), I just installed fish ($ fish --version : fish, version 2.7.1) using the following commands :

sudo apt-add-repository ppa:fish-shell/release-2
sudo apt-get update
sudo apt-get install fish
chsh -s /usr/bin/fish
echo /usr/bin/fish | sudo tee -a /etc/shells

I can launch fish and use it but when I launch a simple shell file like :

echo "something"

I got the following message :

$ ./myscript.sh

Failed to execute process './myscript.sh'. Reason:
exec: Exec format error
The file './myscript.sh' is marked as an executable but could not be run by the operating system.

There's no shebang in my script. If I add #!/usr/bin/env fish, everything's ok (i.e. the script is successfully launched) but I'd like to avoid such a line to keep my script compatible with different shells.

Any idea ?

2

3 Answers 3

13

You need a shebang line if the executable file cannot be run natively by the kernel. The kernel can only run machine code in a specific format (ELF on most Unix variants), or sometimes other formats (e.g. on Linux you can register executable formats through binfmt_misc). If the executable file needs an interpreter then the kernel needs to know which interpreter to call. That's what the shebang line is for.

If your script is in fish syntax, its first line must be

#!/usr/bin/env fish

(You can use the absolute path instead, but then you'll have to modify the script if you want to run it on a machine where the fish executable is in a different location, e.g. /usr/bin/fish vs /usr/local/bin/fish.)

If your script is in sh syntax, use

#!/bin/sh

(All modern Unix systems have a POSIX sh at /bin/sh so you don't need env.)

If your script is in bash syntax (which is sh plus some bash-specific extensions), use

#!/usr/bin/env bash

On Linux, in practice, #!/bin/bash will also work.

All of this is independent of which shell you're calling the script from. All that matters is what language the script is written in.

5

You need to have a shebang in order to execute a script by referencing its path. Otherwise, the operating system will attempt to execute it, but will fail because it's not a binary executable file.

If you don't want to use a shebang you need to specify what should execute the script. In your case, it should be fish.

fish myscript.sh

4
  • Ok, so I'm looking for a 'universal' shebang. What about #!/usr/bin/env bash (see stackoverflow.com/questions/10376206/…) ? This line allows my script to be launched directly with fish.
    – suizokukan
    Commented Dec 29, 2018 at 7:14
  • 1
    @suizokukan: #!/usr/bin/env bash is only universal if every system you want to execute the script has bash installed. If you want portability, write your script to be compatible with POSIX standards. Then most shells will be able to execute it without issue (as most common shells are POSIX compliant).
    – Peschke
    Commented Dec 29, 2018 at 7:31
  • 2
    POSIX scripts don't have the shebang, and since fish isn't POSIX-compatible it can't call them anyway (the premise of this question), so I'm not sure that helps Commented Dec 29, 2018 at 8:06
  • 2
    @MichaelHomer: POSIX scripts can have a shebang if you want them to. Since OP later asked for a ‘universal’ shebang, #!/bin/sh would be the way to go in my opinion.
    – Peschke
    Commented Dec 29, 2018 at 9:20
-2
  1. The following way also works:

    sudo ./<your script>

as it runs bash by default for sudo commands in the most distro. But there might be a reason if you don't want to change the script.

NOTE: that is the wrong way how to solve such problems. Make changes as suggested by Gilles

3
  • Have you tested this with a matching environment to the question? It seems unlikely to me to be a solution.
    – Jeff Schaller
    Commented Dec 13, 2020 at 2:18
  • Yes, definitely tested. I would not post this option without a test. It works. Supposedly, it works as it passes a command directly — without a shell. I tried both Ubuntu 18.04 & 20.04. This ./ — important to mention in the command string. Commented Dec 14, 2020 at 4:38
  • Just tested on Xenai (16.04) — it works this weird way. That is the version of Ubuntu of the original poster. Commented Dec 14, 2020 at 4:44

You must log in to answer this question.

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