Linux Shell脚本在没有shebang行的情况下工作正常吗?为什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12296308/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Shell script working fine without shebang line? Why?
提问by
I was writing a simple shell script and found out that my shell script doesn't require shebang line
我正在编写一个简单的 shell 脚本,发现我的 shell 脚本不需要 shebang 行
#!/bin/sh
If I give execute permissions to my script and execute using ./myscript.sh
. It runs fine.
如果我为我的脚本授予执行权限并使用./myscript.sh
. 它运行良好。
I am using bash
shell and /bin/sh
is actually pointing to bash
.
我正在使用bash
shell 并且/bin/sh
实际上指向bash
.
lrwxrwxrwx 1 root root /bin/sh -> bash
I know that shebang line is used to tell shell which interpreter to use for your rest of the script.
我知道 shebang 行用于告诉 shell 脚本的其余部分使用哪个解释器。
If I miss shebang line in perl, give execute permissions and run ./myscript.pl
, it doesn't work.
如果我错过了 perl 中的 shebang 行,给予执行权限并运行./myscript.pl
,它不起作用。
What's actually happening here? If I use ./
, When is shebang line actually needed?
这里究竟发生了什么?如果我使用./
,什么时候真正需要shebang线?
采纳答案by Michael Krelin - hacker
shebang line is needed inthe file and only if it's meant to be run as executable (as opposed to sh file.sh
invocation. It is not actually needed by script, it is for the system to know how to find interpreter.
文件中需要 shebang 行,并且仅当它打算作为可执行文件运行(而不是sh file.sh
调用。脚本实际上不需要它时,系统才知道如何找到解释器。
EDIT: Sorry for misreading the question. If the shebang line is missing or not recognized, /bin/sh
is used. But I prefer being explicit about the interpreter.
编辑:抱歉误读了这个问题。如果 shebang 行丢失或无法识别,/bin/sh
则使用。但我更喜欢明确解释解释器。
Note, that this behavior is not universal, IIRC, only some exec*
family function do that (not to mention different platforms), so that's another reason to be explicit here.
请注意,这种行为并不普遍,IIRC,只有一些exec*
家族函数会这样做(更不用说不同的平台了),所以这是在这里明确的另一个原因。
回答by Alan Curry
The parent shell, where you entered ./myscript.sh
, first tried to execve
it, which is where the shebang line would take effect if present. When this works, the parent is unaware of the difference between scripts and ELFs because the kernel takes care of it.
您输入的父 shell./myscript.sh
首先尝试execve
它,如果存在,shebang 行将在此处生效。当它起作用时,父进程不知道脚本和 ELF 之间的区别,因为内核会处理它。
The execve
failed, so an ancient unix compatibility feature, predating the existence of shebang lines, was activated. It guessed that a file which has execute permission but is not recognized as a valid executable file by the kernel must be a shell script.
的execve
失败,让一个古老的UNIX兼容的功能,比罗马的家当线的存在,被激活。它猜测具有执行权限但未被内核识别为有效可执行文件的文件必须是shell脚本。
Usually the parent shell guesses that the script is written for the the same shell (minimal Bourne-like shells run the script with /bin/sh
, bash runs it as a bash subprocess),csh does some more complicated guessing based on the first character because it predates shebang too and it needed to coexist with Bourne shell).
通常父 shell 猜测脚本是为同一个 shell 编写的(最小的类似 Bourne 的 shell 使用 运行脚本/bin/sh
,bash 将其作为 bash 子进程运行),csh 根据第一个字符进行一些更复杂的猜测,因为它早于 shebang也需要与 Bourne shell 共存)。
You need a shebang line when you know these guesses will be wrong (for example with the shebang is #!/usr/bin/perl
), or when you don't trust the guessing to work consistently, or when the script needs to be runnable by a parent process that is not a shell itself.
当您知道这些猜测是错误的(例如 shebang is #!/usr/bin/perl
)时,或者当您不相信猜测能够一致工作时,或者当脚本需要由非父进程运行时,您需要一个 shebang 行一个壳本身。
回答by cdarke
The POSIX (Single UNIX Specification 4) standard is not helpful:
POSIX(单一 UNIX 规范 4)标准没有帮助:
If the first line of a file of shell commands starts with the characters "#!" , the results are unspecified.
如果 shell 命令文件的第一行以字符“#!”开头 ,结果未指定。
So, the standard implies that if you don't have #! then it should run a POSIX shell. But modern shells are not POSIX compliant. The old Korn Shell 88 (ksh88) ran the Bourne shell (close to a POSIX shell) with no #! line, but ksh93 breaks that, and so does Bash. With both ksh93 and Bash, they run their own shell if no #! line is present.
因此,该标准意味着如果您没有 #! 那么它应该运行一个POSIX shell。但是现代 shell 不符合 POSIX 标准。旧的 Korn Shell 88 (ksh88) 运行 Bourne shell(接近 POSIX shell)而没有 #! 行,但 ksh93 打破了这一点,Bash 也是如此。使用 ksh93 和 Bash,如果没有 #! 线存在。
Despite popular opinion, Bash and Korn shells differ. When you write a shell script you can never be sure what shell you will be run from, or even if it will be run from another shell at all (most programming languages can run other programs). The minute you use something outside of Bourne/POSIX syntax you will be scuppered.
尽管普遍认为,Bash 和 Korn shell 有所不同。当您编写一个 shell 脚本时,您永远无法确定您将从哪个 shell 运行,甚至根本无法从另一个 shell 运行它(大多数编程语言可以运行其他程序)。一旦你使用了 Bourne/POSIX 语法之外的东西,你就会陷入困境。
Always use a #! line, don't leave it to chance.
始终使用 #! 行,不要让它碰运气。