我意外地使用$!
而不是#!
启动了一个bash脚本,并得到了一些非常奇怪的行为。我想弄清楚发生了什么。
如果你试试这个剧本:
$!/bin/bash
echo Hello world!
您将获得以下行为:
$ chmod +x hello
$ ./hello
[nothing happens, get prompt back]
$ exit
exit
Hello world!
$
所以看起来这件事发生了:
怎么了?怎么样都发生了?如果没有#!
,shell如何知道使用bash
来解释脚本?
显然这是“满足我的好奇心”而不是“解决我的问题”的问题。谷歌搜索不会产生太大的影响,可能是因为查询中的#!
和$!
不会让谷歌机器人感到高兴。
答案 0 :(得分:9)
$ something 是一个参数(“variable”)扩展,但$!
特别返回一个未在脚本中设置的值,所以它扩展为零长度字符串。
因此,您的脚本是正确的,相当于:
/bin/bash
echo Hello world!
shebang magic number是Unix的一个老功能,但shell更老了。内核不能执行的执行位设置的文本文件(因为它实际上没有编译)由子shell执行。也就是说,shell故意运行另一个shell并将路径名作为参数传递。这就是在shebang发明之前执行shell脚本编写的命令,它仍然存在于代码中。
答案 1 :(得分:8)
答案 2 :(得分:3)
对@ DigitalRoss的答案进行了扩展:
第一行没有#!
的可执行脚本由/bin/sh
执行 - 即使您是从bash
(或tcsh
)执行的。这不是shell功能,它在内核中。
因此,当您执行脚本时,它由/bin/sh
执行(这意味着,在大多数系统上,它将无法使用特定于bash的功能),$!
扩展为无(因为该shell没有启动任何后台进程),第一行调用交互式 /bin/bash
shell。然后退出该交互式shell,脚本执行echo Hello world!
行并终止,将您带回原始shell。
例如,如果您将echo Hello world!
更改为echo $BASH_VERSION
,您会发现它不会打印任何内容 - 并且如果您从调用的交互式bash shell中键入history
,它不会显示任何内容。