Shebang标志与set内置标志之间的差异 [英] Difference between shebang flags vs. set builtin flags
问题描述
在Shebang行上传递给脚本的标志与使用set
内置标志的行为是否存在差异?
例如:
#!/bin/bash -e
# do stuff
与
#!/bin/bash
set -e
# do stuff
(问题不是针对-e
标志,而是针对任何此类标志)。
set [flags]
仅从其设置的点起有效。但在功能/行为方面是否还有其他区别?
POSIX外壳中的行为也相同吗?
推荐答案
在功能/行为方面是否有其他差异?
当您的文件具有可执行权限并被执行时,内核将分析Shebang行。
当您的文件像bash ./script.sh
那样在外壳下执行时,Shebang只是一个注释。因此它将被忽略,并且您的脚本将使用任何调用者标志来运行。将您的标志放在Shebang之后将确保在这两种情况下都在脚本中设置了正确的标志。
谢邦是parsed by kernel。这基本上意味着不同的内核、不同的操作系统的行为是不同的。一些操作系统根本不处理Shebang中的参数,并忽略了所有参数。例如,一些内核将#!/bin/sh -a -b
解析为execl("/bin/sh", "-a -b")
,另一些内核解析为execl("/bin/sh", "-a", "-b")
。将shebang行解析为可执行文件和参数是由与您的外壳不同的其他代码完成的。有时,如果#!
LIKE#! /bin/sh
后面有一个空格,实用程序不会将其识别为有效的Shebang。甚至还有最近的linux kernel regression with too long shebang line。
不同的系统解释Shebang的方式不同,因此您无法确定,因此最好在Shebang之后使用set
选项。
POSIX外壳中的行为也相同吗?
POSIX外壳不(必须)解释您的Shebang。如果您询问在POSIX外壳中执行sh -e
和set -e
是否具有相同的行为,则yes, the option -e
on command line与set -e
具有相同的行为。
我找不到Shebang Line的规范,也找不到posix specification中应该如何解释。我可以在Execve文档中看到:
某些历史实现处理外壳脚本的另一种方法是将文件的前两个字节识别为字符串,并将文件第一行的其余部分用作要执行的命令解释程序的名称。
这些历史实现今天似乎仍在广泛使用。
在调用exec*
之后,内核将解析Shebang行。但是,当您执行sh <script>
或popen
或system
时,外壳可以(但不必)将shebang行本身解释为扩展,而不依赖于POSIX:
外壳介绍
- 外壳从文件(请参阅sh)、
−c
选项或POSIX.1-200x的系统接口卷中定义的system()
和popen()
函数读取其输入。如果外壳命令文件的第一行以字符";#!";开头,则结果未指定。
至于bash,看起来像bashfirst tries execve,如果找不到内核无法运行可执行文件的原因,则if the file has a shebang,然后it parses shebang on its own找出解释器。
这篇关于Shebang标志与set内置标志之间的差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!