鱼壳:执行格式错误

sui*_*kan 8 shell shell-script fish

在 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) 上,我刚刚使用以下命令安装了fish ( $ fish --version: fish, version 2.7.1):

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
Run Code Online (Sandbox Code Playgroud)

我可以启动fish并使用它,但是当我启动一个简单的 shell 文件时,例如:

echo "something"
Run Code Online (Sandbox Code Playgroud)

我收到以下消息:

$ ./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.
Run Code Online (Sandbox Code Playgroud)

我的脚本中没有shebang。如果我添加#!/usr/bin/env fish,一切正常(即脚本已成功启动),但我想避免使用这样的行以保持我的脚本与不同的 shell 兼容。

任何的想法 ?

Gil*_*il' 12

如果可执行文件不能由内核本地运行,则需要一个 shebang 行。内核只能运行特定格式的机器代码(大多数 Unix 变体上的ELF),或者有时其他格式(例如,在 Linux 上,您可以通过binfmt_misc注册可执行格式)。如果可执行文件需要解释器,那么内核需要知道要调用哪个解释器。这就是shebang线的用途。

如果你的脚本是fish语法,它的第一行必须是

#!/usr/bin/env fish
Run Code Online (Sandbox Code Playgroud)

(您可以改用绝对路径,但是如果您想在fish可执行文件位于不同位置的机器上运行它,则必须修改脚本,例如/usr/bin/fishvs /usr/local/bin/fish。)

如果您的脚本是 sh 语法,请使用

#!/bin/sh
Run Code Online (Sandbox Code Playgroud)

(所有现代 Unix 系统都有一个 POSIX sh at/bin/sh所以你不需要env。)

如果您的脚本采用 bash 语法(即 sh 加上一些特定于 bash 的扩展名),请使用

#!/usr/bin/env bash
Run Code Online (Sandbox Code Playgroud)

实际上,在 Linux 上#!/bin/bash也可以使用。

所有这些都与您从哪个 shell 调用脚本无关。重要的是脚本是用什么语言编写的。


Pes*_*hke 5

您需要有一个shebang才能通过引用其路径来执行脚本。否则,操作系统将尝试执行它,但会失败,因为它不是二进制可执行文件。

如果您不想使用shebang,则需要指定应该执行脚本的内容。在你的情况下,它应该是fish.

fish myscript.sh

  • POSIX 脚本没有shebang,并且由于fish 与POSIX 不兼容,因此无论如何都不能调用它们(这个问题的前提),所以我不确定这有帮助 (2认同)
  • @MichaelHomer:如果你愿意,POSIX 脚本可以有一个shebang。由于 OP 后来要求使用“通用”shebang,因此在我看来,`#!/bin/sh` 将是可行的方法。 (2认同)