为什么所有的脚本文件都以 </ 开头?
#!/bin/sh
或者使用。#!/bin/csh
那是必需的吗?这是什么目的?两者之间有什么区别?
这被称为Shebang
:
http://en.wikipedia.org/wiki/Shebang_(Unix)
#!解释器 [可选参数]
只有在脚本具有执行权限时(例如chmod u+x script.sh),才与 Shebang 相关。
当 shell 执行脚本时,它将使用指定的解释器。
例如:
#!/bin/bash
# file: foo.sh
echo 1
$ chmod u+x foo.sh
$ ./foo.sh
1
#!
这一行告诉内核(具体来说,是execve
系统调用的实现),这个程序是用解释型语言编写的;随后的绝对路径标识了解释器。编译成机器代码的程序以不同的字节序列开头--在大多数现代Unix中,是7f 45 4c 46
(^?ELF),以此来辨别它们。#!
脚本,你可以在#!
后面放置任何程序的绝对路径。内核会重新编写调用。./script arg1 arg2 arg3 ...
当以#! /usr/bin/perl
开头的时候,./script
就会开始运行,就好像命令行实际上是这样的
/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
。setuid
或setgid
权限的程序无法使用#!
;它们必须被编译为机器代码。(如果您不知道setuid
是什么,请不要担心这个)。关于csh
,它与sh
的关系大致如同Nutrimat Advanced Tea Substitute和茶的关系。对于交互使用,它比sh
有一些优势(或者说曾经有过,现代实现的sh
已经追赶上来了),但是将其(或其后代tcsh
)用于脚本编写几乎总是错误的。如果你是初学者,我强烈建议你忽略它,专注于sh
。如果你正在使用csh
相对作为登录shell,请切换到bash
或zsh
,这样交互式命令语言就与你正在学习的脚本语言相同。
#!/bin/csh
表示C shell,/bin/tcsh
表示t shell,/bin/bash
表示bash shell等。你可以通过命令找出你正在使用的交互式shell。 echo $SHELL
env | grep -i shell
chsh
命令更改您的命令shell。tcsh
shell,但经常使用脚本文件中的/bin/bash运行bash脚本。 #!/usr/bin/python
在你的Python程序顶部
#! $SHELL
的事情吗?这样会将正确的shell放入Shebang中吗? - One Two Three!#/bin/bash
指令的美妙之处。它告诉系统使用哪个 shell 来执行你的 shell 脚本。 - Levon$SHELL
的值并不能确定你当前正在使用哪个 shell;它通常只是告诉你你的默认 shell。tcsh 设置 $version
和 $tcsh
;bash 设置 $BASH_VERSION
。并非所有 shell 都必须有类似的机制。 - Keith Thompson#!
行必须与脚本的语法匹配,而不是运行脚本的交互式 shell 的语法。 - Keith Thompson
#!/bin/csh -f
;-f
告诉shell不要源用户的.login
和.cshrc
,这使得脚本运行更快,并避免了对用户设置的依赖。(或者最好不要编写csh脚本。)不要为sh或bash脚本使用-f
;它没有相同的含义。 - Keith Thompson