标签: shebang

为什么最好使用“#!/usr/bin/env NAME”而不是“#!/path/to/NAME”作为我的shebang?

我注意到我从其他人那里获得的一些脚本有 shebang#!/path/to/NAME而其他人(使用相同的工具,NAME)有 shebang #!/usr/bin/env NAME

两者似乎都可以正常工作。在教程中(例如在 Python 上),似乎有人建议后者 shebang 更好。但是,我不太明白为什么会这样。

我意识到,为了使用后一个 shebang,NAME 必须在 PATH 中,而第一个 shebang 没有这个限制。

此外,(对我而言)第一个似乎是更好的shebang,因为它精确地指定了NAME 所在的位置。因此,在这种情况下,如果 NAME 有多个版本(例如,/usr/bin/NAME、/usr/local/bin/NAME),第一种情况指定使用哪个。

我的问题是为什么第一个shebang比第二个更受欢迎?

shell-script shebang

588
推荐指数
10
解决办法
25万
查看次数

shebang 是否确定运行脚本的 shell?

这可能是一个愚蠢的问题,但我仍然问它。如果我已经宣布了一个shebang

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

在开始时my_shell_script.sh,我是否总是必须使用 bash 调用此脚本

[my@comp]$bash my_shell_script.sh
Run Code Online (Sandbox Code Playgroud)

或者我可以使用例如

[my@comp]$sh my_shell_script.sh
Run Code Online (Sandbox Code Playgroud)

我的脚本使用shebang确定正在运行的shell?难道同样的事情发生与ksh壳呢?我正在使用 AIX。

scripting executable shebang

110
推荐指数
4
解决办法
8万
查看次数

#!/bin/bash - 没有这样的文件或目录

我已经创建了一个 bash 脚本,但是当我尝试执行它时,我得到

#!/bin/bash no such file or directory
Run Code Online (Sandbox Code Playgroud)

我需要运行命令:bash script.sh让它工作。

我怎样才能解决这个问题?

bash executable shell-script shebang

94
推荐指数
4
解决办法
30万
查看次数

为什么下面的脚本会删除自己?

如果您创建一个包含以下内容的可执行文件并运行它,它会自行删除。
这是如何运作的?

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

executable shell-script rm files shebang

84
推荐指数
1
解决办法
1万
查看次数

shebang中的多个参数

我想知道是否有通过 shebang 行 ( #!)将多个选项传递给可执行文件的通用方法。

我使用 NixOS,在我编写的任何脚本中,shebang 的第一部分通常是/usr/bin/env. 然后我遇到的问题是系统将其后的所有内容解释为单个文件或目录。

例如,假设我想编写一个脚本以bash在 posix 模式下执行。写shebang的天真方式是:

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

但是尝试执行生成的脚本会产生以下错误:

/usr/bin/env: ‘bash --posix’: No such file or directory
Run Code Online (Sandbox Code Playgroud)

我知道这篇文章,但我想知道是否有更通用和更清洁的解决方案。


编辑:我知道对于Guile脚本,有一种方法可以实现我想要的,在手册的第 4.3.4 节中记录:

 #!/usr/bin/env sh
 exec guile -l fact -e '(@ (fac) main)' -s "$0" "$@"
 !#
Run Code Online (Sandbox Code Playgroud)

这里的技巧是,第二行(以 开头exec)被解释为代码,sh但是,在#!...!#块中,作为注释,因此被 Guile 解释器忽略。

难道不能将此方法推广到任何解释器吗?


第二次编辑:在玩了一会儿之后,似乎对于可以从中读取输入的解释器,stdin以下方法可以工作:

#!/usr/bin/env sh
sed '1,2d' "$0" | bash --verbose --posix …
Run Code Online (Sandbox Code Playgroud)

scripting environment-variables posix arguments shebang

68
推荐指数
5
解决办法
2万
查看次数

Shebang以`//`开头?

我对以下脚本 ( hello.go)感到困惑。

//usr/bin/env go run $0 $@ ; exit

package main
import "fmt"
func main() {
    fmt.Printf("hello, world\n")
}
Run Code Online (Sandbox Code Playgroud)

它可以执行。(在 MacOS X 10.9.5 上)

$ chmod +x hello.go
$ ./hello.go
hello, world
Run Code Online (Sandbox Code Playgroud)

我还没有听说过以 开头的shebang //。当我在脚本顶部插入一个空行时,它仍然有效。为什么这个脚本有效?

osx shell slash shell-script shebang

62
推荐指数
2
解决办法
4023
查看次数

#! 之间是否允许空格?和/bin/bash 在shebang?

在shebang中,#!和解释器之间是否允许有一个或更多的空间?

例如,#! /bin/bash。看起来可行,但有人说这是不正确的。

shebang

59
推荐指数
3
解决办法
1万
查看次数

有什么理由让shebang指向/bin/sh而不是/bin/bash?

在我见过的大多数 shell 脚本中(除了我自己没有写的脚本),我注意到 shebang 设置为#!/bin/sh. 这在旧脚本上并没有让我感到惊讶,但在相当新的脚本上也是如此。

是否有任何理由宁愿/bin/sh/bin/bash,因为bash几乎是无处不在的,而且往往默认情况下,许多Linux和BSD的机器回去了十多年?

shell bash history shebang

54
推荐指数
5
解决办法
6513
查看次数

bash 脚本使用 .sh 或 .bash 扩展名?

(有关Ubuntu-OSX 兼容性和易用性以及 POSIX,请参阅使用 #!/bin/sh 或 #!/bin/bash

如果我希望我的脚本使用 bash shell,那么使用 .bash 扩展名实际上是调用 bash 还是依赖于系统配置/第一个 shebang 行。如果两者都有效但不同,哪个优先?

我不确定是否用 .sh 结束我的脚本以仅指示“shell 脚本”,然后让第一行选择 bash shell(例如#!/usr/bin/env bash),或者是否只用 .bash 结束它们(以及第 1 行设置) )。我想调用 bash。

shell bash shebang

39
推荐指数
2
解决办法
6万
查看次数

当我在我的 shell 中执行一个文件时到底发生了什么?

所以,我以为我对此有一个很好的理解,但只是进行了一个测试(以回应我不同意某人的对话)并发现我的理解有缺陷......

尽可能详细地说明当我在 shell 中执行文件时到底发生了什么?我的意思是,如果我输入:./somefile some arguments进入我的 shell 并按回车键(并且somefile存在于 cwd 中,并且我有读取+执行权限somefile),那么引擎盖下会发生什么?

以为答案是:

  1. 外壳程序对 进行系统调用exec,将路径传递给somefile
  2. 内核检查somefile并查看文件的幻数,以确定它是否是处理器可以处理的格式
  3. 如果幻数表明文件是处理器可以执行的格式,那么
    1. 创建一个新进程(在进程表中有一个条目)
    2. somefile被读取/映射到内存。创建堆栈并执行跳转到代码的入口点somefile,并ARGV初始化为参数数组 (a char**, ["some","arguments"])
  4. 如果幻数是shebang,exec()如上所述生成一个新进程,但使用的可执行文件是shebang(例如/bin/bash/bin/perl)引用的解释器并somefile传递给STDIN
  5. 如果文件没有有效的幻数,则会出现“无效文件(错误的幻数):Exec 格式错误”之类的错误

但是有人告诉我,如果文件是纯文本,那么 shell 会尝试执行命令(就像我输入了bash somefile)。我不相信这一点,但我只是尝试了一下,结果是正确的。所以我显然对这里实际发生的事情有一些误解,并想了解机制。

当我在我的 shell 中执行一个文件时到底发生了什么?(尽可能多的细节是合理的......)

shell kernel exec shebang

38
推荐指数
3
解决办法
5761
查看次数