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
#行不是必需的(如果存在将被忽略),并且文件不必是可执行的。该特性的要点是允许您直接调用解释语言程序,而不必知道它们是用什么语言编写的。(Do
grep'^#!'/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。(不幸的是,这个人对这些东西一无所知,因此他所能做的就是运行脚本而不改变任何东西)。我能做一些像
#这样的事情吗$外壳
?沃