shell脚本头(#!/bin/sh vs#!/bin/csh)
为什么所有脚本文件都以shell脚本头(#!/bin/sh vs#!/bin/csh),shell,unix,Shell,Unix,为什么所有脚本文件都以 #!/bin/sh 或与 #!/bin/csh 需要吗?这样做的目的是什么?两者之间有什么区别?这定义了用于解释/运行脚本的shell(命令解释器)。每个shell与用户交互和执行脚本(程序)的方式略有不同 在Unix提示符下键入命令时,您正在与shell交互 例如,#/bin/csh指的是C-shell,/bin/tcsh指的是t-shell,/bin/bash指的是bash-shell,等等 您可以判断使用的是哪个交互式shell echo $SHELL 命令
#!/bin/sh
或与
#!/bin/csh
需要吗?这样做的目的是什么?两者之间有什么区别?这定义了用于解释/运行脚本的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中的语句不同
可能会感兴趣,因为它在bash和tcsh命令/语法之间“转换”
在shell脚本中使用该指令允许您使用不同的shell运行程序。例如,我以交互方式使用tcsh
shell,但通常在脚本文件中使用/bin/bash运行bash脚本
旁白:
这个概念也扩展到其他脚本。例如,如果你用Python编程,你会
#!/usr/bin/python
在Python程序的顶部,这被称为
Shebang
:
#!!解释器[可选参数]
shebang仅在脚本具有执行权限时才相关(例如chmod u+x script.sh)
当shell执行脚本时,它将使用指定的解释器
例如:
#!/bin/bash
# file: foo.sh
echo 1
$ chmod u+x foo.sh
$ ./foo.sh
1
#代码>行告诉内核(特别是系统调用的实现)这个程序是用解释语言编写的;后面的绝对路径名标识解释器。编译成机器码的程序以一个不同的字节序列开始——在大多数现代Unix上,7F454C46
(^?ELF)将它们识别为不同的字节序列
您可以在#之后放置任何程序的绝对路径代码>,只要该程序本身不是#代码>脚本。内核重写了对
./script arg1 arg2 arg3 ...
其中/script
以,比如说,#开头/usr/bin/perl
,就好像命令行实际上是
/usr/bin/perl ./script arg1 arg2 arg3
或者,如您所见,您可以使用#/bin/sh
编写一个脚本,由sh
解释
#仅当您直接调用脚本(命令行上的/script
)时,才会处理代码>行;该文件还必须是可执行文件(chmod+x脚本
)。如果您执行sh./script
the#代码>行不是必需的(如果存在将被忽略),并且文件不必是可执行的。该特性的要点是允许您直接调用解释语言程序,而不必知道它们是用什么语言编写的。(Dogrep'^#!'/usr/bin/*
——你会发现很多股票程序实际上都在使用此功能。)
以下是使用此功能的一些规则:
#
必须是文件中的前两个字节。特别是,文件必须采用ASCII兼容编码(例如UTF-8可以工作,但UTF-16不能),并且不能以“字节顺序标记”开头,否则内核将无法将其识别为#代码>脚本
#之后的路径代码>必须是绝对路径(以/
开头)。它不能包含空格、制表符或换行符
- 在
#之间加一个空格是很好的风格,但不是必需的代码>和/
。不要在那里放置多个空格
- 不能在
#上放置shell变量代码>行,它们将不会展开
- 您可以将一个命令行参数放在绝对路径之后,并用一个空格分隔。与绝对路径一样,此参数不能包含空格、制表符或换行符。有时这是使事情正常运行所必需的(
#!/usr/bin/awk-f
),有时它只是有用的(#!/usr/bin/perl-Tw
)。不幸的是,您不能在绝对路径后放置两个或多个参数
- 有些人会告诉你使用
#/usr/bin/env解释器
而不是#/绝对/路径/到/解释器
这几乎总是一个错误。它使程序的行为取决于调用脚本的用户的$PATH
变量。而且并非所有系统首先都有env
- 需要
setuid
或setgid
权限的程序不能使用#代码>;它们必须被编译成机器代码。(如果您不知道什么是setuid
,请不要担心。)
关于csh
,它与sh
的关系大致与Nutrimat与茶的关系相同。与sh
相比,它在交互使用方面有许多优势(或者说,它已经赶上了sh
的现代实现),但是使用它(或者它的后代tcsh
)编写脚本是非常困难的。如果您一般不熟悉shell脚本,我强烈建议您忽略它,将重点放在sh
上。如果您使用csh
亲戚作为登录shell,请切换到bash
或zsh
,以便交互式命令语言与您正在学习的脚本语言相同。是否需要?我如何知道我真正使用的是哪个shell呢?因此,如果我在为某人编写脚本以在他们的机器上使用,而我不知道他们使用的是什么shell。(不幸的是,这个人对这些东西一无所知,因此他所能做的就是运行脚本而不改变任何东西)。我能做一些像#这样的事情吗$外壳
?沃