shell脚本头文件(#!/ bin/sh vs#!/ bin/csh)

One*_*ree 72 unix shell

为什么所有脚本文件都以

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

或者

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

这需要吗?这是为了什么目的?这两者有什么区别?

kwa*_*ick 85

这被称为Shebang:

http://en.wikipedia.org/wiki/Shebang_(Unix)

#!interpreter [optional-arg]

只有当脚本具有执行权限(例如chmod u + x script.sh)时,shebang才有意义.

当shell执行脚本时,它将使用指定的解释器.

例:

#!/bin/bash
# file: foo.sh
echo 1

$ chmod u+x foo.sh
$ ./foo.sh
  1
Run Code Online (Sandbox Code Playgroud)


zwo*_*wol 38

#!行告诉内核(具体来说,execve系统调用的实现)该程序是用解释语言编写的; 后面的绝对路径名标识解释器.编译为机器代码的程序以不同的字节序列开始 - 在大多数现代Unix上,7f 45 4c 46(^?ELF)标识它们.

只要该程序本身不是脚本,您就可以将绝对路径放在所需的任何程序之后.内核重写了一个调用#!#!

./script arg1 arg2 arg3 ...
Run Code Online (Sandbox Code Playgroud)

哪里./script有,比如说开始,#! /usr/bin/perl作为如果在命令行实际上曾经一向是

/usr/bin/perl ./script arg1 arg2 arg3
Run Code Online (Sandbox Code Playgroud)

或者,正如您所见,您可以使用#! /bin/sh编写一个旨在解释的脚本sh.

#!,如果你线只处理直接调用脚本(./script在命令行上); 该文件也必须是可执行的(chmod +x script).如果你sh ./script#!线是没有必要的(如果存在的话会被忽略),该文件并不一定是可执行的.该功能的要点是允许您直接调用解释语言程序,而无需知道它们所使用的语言.(请grep '^#!' /usr/bin/*- 您会发现很多库存程序实际上都在使用此功能.)

以下是使用此功能的一些规则:

  • #!必须是非常前两个字节的文件中.特别是,文件必须是ASCII兼容的编码(例如,UTF-8可以工作,但UTF-16不会),并且不能以"字节顺序标记"开头,否则内核不会将其识别为#!脚本.
  • 后面的路径#!必须是绝对路径(以...开头/).它不能包含空格,制表符或换行符.
  • 在它和它之间留一个空间是好的风格,但不是必需#!/.不要在那里放置多个空间.
  • 你不能把shell变量放在#!行上,它们不会被扩展.
  • 您可以在绝对路径之后放置一个命令行参数,并将其与单个空格分隔开.与绝对路径一样,此参数不能包含空格,制表符或换行符.有时这是让事情发挥作用的必要条件(#! /usr/bin/awk -f),有时它只是有用的(#! /usr/bin/perl -Tw).不幸的是,你不能在绝对路径之后放两个或更多个参数.
  • 有些人会告诉你使用#! /usr/bin/env interpreter而不是#! /absolute/path/to/interpreter.这几乎总是一个错误.它使程序的行为取决于$PATH调用脚本的用户的变量.并非所有系统都具有env首要功能.
  • 需要setuidsetgid特权的程序无法使用#!; 它们必须编译为机器代码.(如果你不知道是什么setuid,不要担心这个.)

关于csh,它sh大致与Nutrimat 高级茶替代品有关.它具有(或更确切地说,现代实现sh已经赶上)sh交互式使用的许多优点,但使用它(或其后代tcsh)进行脚本编写几乎总是一个错误.如果您不熟悉shell脚本,我强烈建议您忽略它并专注于sh.如果您使用csh亲戚作为登录shell,请切换到bashzsh,以便交互式命令语言与您正在学习的脚本语言相同.


Lev*_*von 5

这定义了您用于解释/运行脚本的 shell(命令解释器)。每个 shell 与用户交互和执行脚本(程序)的方式略有不同。

当您在 Unix 提示符下键入命令时,您正在与 shell 进行交互。

例如,#!/bin/csh指的是 C-shell、/bin/tcsht-shell、/bin/bashbash shell 等。

你可以告诉你正在使用哪个交互式 shell

 echo $SHELL
Run Code Online (Sandbox Code Playgroud)

命令,或者

 env | grep -i shell
Run Code Online (Sandbox Code Playgroud)

您可以使用该chsh命令更改您的命令外壳。

每个都有一个稍微不同的命令集和分配变量的方式以及它自己的一组编程结构。例如,带有 bash 的 if-else 语句看起来与 C-shell 中的语句不同。

这个页面可能很有趣,因为它在 bash 和 tcsh 命令/语法之间“翻译”。

在 shell 脚本中使用指令允许您使用不同的 shell 运行程序。例如,我以tcsh交互方式使用shell,但经常在脚本文件中使用 /bin/bash 运行 bash 脚本。

在旁边:

这个概念也扩展到其他脚本。例如,如果你用 Python 编程,你就会把

 #!/usr/bin/python
Run Code Online (Sandbox Code Playgroud)

在你的 Python 程序的顶部