use*_*970 12 shell-script shebang syntax
我有一个由大约 20 个小.sh
文件组成的项目。我将这些命名为“小”是因为一般来说,没有文件超过 20 行代码。我采用了模块化方法,因为这样我忠于Unix 哲学,而且对我来说维护项目更容易。
在每个.sh
文件的开头,我把#!/bin/bash
.
简单地说,我理解脚本声明有两个目的:
当一个项目开始从 5 个文件增长到 20 个文件或从 20 个文件增长到 50 个文件时(不是这种情况,只是为了演示)我们有 20 行或 50行脚本声明。我承认,尽管对某些人来说可能很有趣,但使用 20 或 50 个而不是每个项目仅使用1 个(可能在项目的主文件中)对我来说感觉有点多余。
有没有办法通过在某个主文件中使用一些“全局”脚本声明来避免这种所谓的 20 或 50 行或更多行的脚本声明冗余?
Kus*_*nda 19
即使您的项目现在可能仅由 50 个 Bash 脚本组成,它迟早会开始积累用其他语言编写的脚本,例如 Perl 或 Python(因为这些脚本语言具有 Bash 没有的优点)。
如果#!
每个脚本中没有合适的-line,那么在不知道要使用什么解释器的情况下使用各种脚本将是非常困难的。如果每个脚本都从其他脚本执行并不重要,这只会将难度从最终用户转移到开发人员。这两组人都不需要知道脚本是用什么语言编写的才能使用它。
在没有#!
-line 和显式解释器的情况下执行的Shell 脚本以不同的方式执行,具体取决于调用它们的 shell(参见例如问题哪个 shell 解释器运行没有 shebang 的脚本?尤其是Stéphane 的回答),这不是您想要的在生产环境中(您想要一致的行为,甚至可能是可移植性)。
无论#!
-line 说什么,使用显式解释器执行的脚本都将由该解释器运行。如果您决定在 Python 或任何其他语言中重新实现 Bash 脚本,这将进一步导致问题。
您应该花费这些额外的按键,并始终#!
为每个脚本添加一个-line。
在某些环境中,每个项目的每个脚本中都有多段样板法律文本。很高兴它只是#!
在您的项目中感觉“冗余”的-line。
Ste*_*ris 11
你误解了#!
. 它实际上是对操作系统的指令,使其在定义的解释器下运行该程序。
因此,可以使用脚本,#!/usr/bin/perl
并且可以运行生成的程序,./myprogram
并且可以使用 perl 解释器。类似#!/usr/bin/python
会导致程序在 python 下运行。
所以这行#!/bin/bash
告诉操作系统在 bash 下运行这个程序。
下面是一个例子:
$ echo $0
/bin/ksh
$ cat x
#!/bin/bash
ps -aux | grep $$
$ ./x
sweh 2148 0.0 0.0 9516 1112 pts/5 S+ 07:58 0:00 /bin/bash ./x
sweh 2150 0.0 0.0 9048 668 pts/5 S+ 07:58 0:00 grep 2148
Run Code Online (Sandbox Code Playgroud)
因此,尽管我的 shell 是 ksh,但由于该#!
行,程序“x”在 bash 下运行,我们可以在进程列表中明确看到这一点。
.sh
不好的是.sh
文件名的末尾。
想象一下,您用 Python 重写了其中一个脚本。
好吧,现在您必须将第一行更改#!/usr/bin/python3
为此还不错,因为您还必须更改文件中的所有其他代码行。但是,您还必须将文件名从 更改prog.sh
为prog.py
. 然后您必须在其他脚本中的任何地方找到您的所有用户脚本(您甚至不知道存在的脚本),并将它们更改为使用新脚本。sed -e 's/.sh/.py/g'
可能对你认识的人有所帮助。但是现在您的修订控制工具显示了许多不相关文件的变化。
或者,以 Unix 方式进行操作并将程序命名为prog
not prog.sh
。
#!
如果您有正确的#!
,并将权限/模式设置为包括执行。那么你就不需要认识口译员了。电脑会为你做的。
chmod +x prog #on gnu adds execute permission to prog.
./prog #runs the program.
Run Code Online (Sandbox Code Playgroud)
对于非 gnu 系统,请阅读手册chmod
(并学习八进制),无论如何都可以阅读。
[hashbang 行]确保脚本仅在某个 shell(在这种情况下为 Bash)运行,以防止在使用另一个 shell 时出现意外行为。
可能值得指出的是,这是完全错误的。hashbang 行绝不会阻止您尝试将文件提供给不正确的 shell/解释器:
$ cat array.sh
#!/bin/bash
a=(a b c)
echo ${a[1]} $BASH_VERSION
$ dash array.sh
array.sh: 2: array.sh: Syntax error: "(" unexpected
Run Code Online (Sandbox Code Playgroud)
(或与awk -f array.sh
等类似)
但无论如何,模块化的另一种方法是在文件中定义 shell 函数,每个文件一个函数,如果你愿意,然后source
是主程序中的文件。这样,您就不需要 hashbangs:它们将被视为任何其他注释,并且所有内容都将使用相同的 shell 运行。不利的一面是您需要source
使用具有函数的文件(例如for x in functions/*.src ; do source "$x" ; done
),并且它们都使用相同的 shell 运行,因此您不能直接用 Perl 实现替换其中之一。
归档时间: |
|
查看次数: |
1841 次 |
最近记录: |