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

时间:2012-05-14 21:08:22

标签: shell unix

为什么所有脚本文件都以

开头
#!/bin/sh

#!/bin/csh

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

3 个答案:

答案 0 :(得分:77)

这称为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

答案 1 :(得分:38)

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

只要该程序本身不是#!脚本,您就可以在#!之后为所需的任何程序设置绝对路径。内核重写了

的调用
./script arg1 arg2 arg3 ...

其中./script#! /usr/bin/perl开头,好像命令行实际上是

/usr/bin/perl ./script arg1 arg2 arg3

或者,正如您所见,您可以使用#! /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 Advanced Tea Substitute对茶一样。它具有(或更确切地说,sh的现代实现已经赶上了)sh对于交互式使用的许多优势,但使用它(或其后代tcsh)进行脚本编写是{ {3}}。如果您不熟悉shell脚本,我强烈建议您忽略它并专注于sh。如果您使用csh亲戚作为登录shell,请切换到bashzsh,以便交互式命令语言与您正在学习的脚本语言相同。 / p>

答案 2 :(得分:4)

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

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

例如,#!/bin/csh指的是C-shell,/bin/tcsh t-shell,/bin/bash bash shell等。

您可以告诉使用

的交互式shell
 echo $SHELL

命令,或者

 env | grep -i shell

您可以使用chsh命令更改命令shell。

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

This page可能会引起关注,因为它在bash和tcsh命令/语法之间进行“翻译”。

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

除了:

这个概念也扩展到其他脚本。例如,如果您使用Python编程,则需要输入

 #!/usr/bin/python

位于Python程序的顶部