常见的Shell 与 释伴(#!) Shebang 符号
常见的Shell
shell 介绍
Linux 是一个开源的操作系统,由分布在世界各地的多个组织机构或个人共同开发完成,每个组织结构或个人负责一部分功能,最后组合在一起,就构成了今天的 Linux。例如:
Linux 内核最初由芬兰黑客 Linus Torvalds 开发,后来他组建了团队,Linux 内核由这个团队维护。
GNU 组织开发了很多核心软件和基础库,例如 GCC 编译器、C语言标准库、文本编辑器 Emacs、进程管理软件、Shell 以及GNOME 桌面环境等。
VIM 编辑器由荷兰人 Bram Moolenaar 开发。
Windows、Mac OS、Android 等操作系统不一样,它们都由一家公司开发,所有的核心软件和基础库都由一家公司做决定,容易形成统一的标准,一般不会开发多款功能类似的软件。
而 Linux 不一样,它是“万国牌”,由多个组织机构开发,不同的组织机构为了发展自己的 Linux 分支可能会开发出功能类似的软件,它们各有优缺点,用户可以自由选择。Shell 就是这样的一款软件,不同的组织机构开发了不同的 Shell,它们各有所长,有的占用资源少,有的支持高级编程功能,有的兼容性好,有的重视用户体验。
Shell 既是一种脚本编程语言,也是一个连接内核和用户的软件。
常见的 Shell 有 sh、bash、csh、tcsh、ash 等。
- sh
- sh 的全称是 Bourne shell,由 AT&T 公司的 Steve Bourne开发,为了纪念他,就用他的名字命名了。
- sh 是 UNIX 上的标准 shell,很多 UNIX 版本都配有 sh。sh 是第一个流行的 Shell。
- csh
- sh 之后另一个广为流传的 shell 是由柏克莱大学的 Bill Joy 设计的,这个 shell 的语法有点类似C语言,所以才得名为 C shell ,简称为 csh。
Bill Joy 是一个风云人物,他创立了 BSD 操作系统,开发了 vi 编辑器,还是 Sun 公司的创始人之一。
BSD 是 UNIX 的一个重要分支,后人在此基础上发展出了很多现代的操作系统,最著名的有 FreeBSD、OpenBSD 和 NetBSD,就连 Mac OS X 在很大程度上也基于BSD。
- tcsh
- tcsh 是 csh 的增强版,加入了命令补全功能,提供了更加强大的语法支持。
- ash
- 一个简单的轻量级的 Shell,占用资源少,适合运行于低内存环境,但是与下面讲到的 bash shell 完全兼容
- bash
- bash shell 是 Linux 的默认 shell,本教程也基于 bash 编写。
- bash 由 GNU 组织开发,保持了对 sh shell 的兼容性,是各种 Linux 发行版默认配置的 shell。
- bash 兼容 sh 意味着,针对 sh 编写的 Shell 代码可以不加修改地在 bash 中运行。
尽管如此,bash 和 sh 还是有一些不同之处:
一方面,bash 扩展了一些命令和参数;
另一方面,bash 并不完全和 sh 兼容,它们有些行为并不一致,但在大多数企业运维的情况下区别不大,特殊场景可以使用 bash 代替 sh。
- zsh
- zsh配置复杂,所以很多人都不会使用。直到有一天出了 Oh My Zsh项目,才让更多人发现并开始使用zsh。有人说zsh是终极shell。zsh很漂亮,很炫酷,以前是极客使用,现在小白通过oh-my-zsh可以炫耀。
查看 Shell
Shell 是一个程序,一般都是放在/bin或者/user/bin目录下,当前 Linux 系统可用的 Shell 都记录在/etc/shells文件中。/etc/shells是一个纯文本文件,你可以在图形界面下打开它,也可以使用 cat 命令查看它。
通过 cat 命令来查看当前 Linux 系统的可用 Shell:
$ cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh
在现代的 Linux 上,sh 已经被 bash 代替,/bin/sh往往是指向/bin/bash的符号链接。
如果你希望查看当前 Linux 的默认 Shell,那么可以输出 SHELL 环境变量:
$ echo $SHELL
/bin/bash
输出结果表明默认的 Shell 是 bash。
echo是一个 Shell 命令,用来输出变量的值,我们将在《Shell echo命令》中详细介绍它的用法。SHELL是 Linux 系统中的环境变量,它指明了当前使用的 Shell 程序的位置,也就是使用的哪个 Shell。
切换默认的Shell
chsh -s [shell的二进制文件路径],之后要重新登陆Shell才能生效:
##例如:
#切换为Bash:
chsh -s /bin/bash#切换为Zsh:
chsh -s /bin/zsh
Shebang符号(#!)
这个符号的名称,叫做”Shebang”或者”Sha-bang”。长期以来,Shebang都没有正式的中文名称。Linux中国翻译组的GOLinux将其翻译为“释伴”,即“解释伴随行”的简称,同时又是Shebang的音译。本文将简单介绍一下Shebang这个符号。
-
词源与历史
Shebang 的名字来自于 SHArp 和 bang,或 haSH bang 的缩写,指代 Shebang 中 #! 两个符号的典型 Unix 名称。 Unix 术语中,井号通常称为 sharp,hash 或 mesh;而叹号则常常称为 bang。也有看法认为,shebang 名字中的 sh 来自于默认shell Bourne shell 的名称,sh,因为常常使用 shebang 调用之。
在2010年版的 Advanced bash scripting guide(revision 6.2)中,Shebang 被称为 “sha-bang”,同时提到”也写作 she-bang 或 sh-bang”,但该文件中没有提到 “shebang” 这一形式。 -
用法
Shebang通常出现在类Unix系统的脚本中第一行,作为前两个字符。在Shebang之后,可以有一个或数个空白字符,后接解释器的绝对路径,用于指明执行这个脚本文件的解释器。在直接调用脚本时,系统的程序载入器会分析 Shebang 后的内容,将这些内容作为解释器指令,并调用该指令,将载有 Shebang 的文件路径作为该解释器的参数,执行脚本,从而使得脚本文件的调用方式与普通的可执行文件类似。例如,以指令#!/bin/sh开头的文件,在执行时会实际调用 /bin/sh 程序(通常是 Bourne shell 或兼容的 shell,例如 bash、dash 等)来执行。
由于 # 符号在许多脚本语言中都是注释标识符,Shebang 的内容会被这些脚本解释器自动忽略。 在 # 字符不是注释标识符的语言中,例如 Scheme,解释器也可能忽略以 #! 开头的首行内容,以提供与shebang 的兼容性。
示例:
- 如果脚本文件中没有#!这一行,那么执行时会默认采用当前Shell去解释这个脚本(即:$SHELL环境变量)。
- 如果#!之后的解释程序是一个可执行文件,那么执行这个脚本时,它就会把文件名及其参数一起作为参数传给那个解释程序去执行。
- 如果#!指定的解释程序没有可执行权限,则会报错“bad interpreter: Permission denied”。如果#!指定的解释程序不是一个可执行文件,那么指定的解释程序会被忽略,转而交给当前的SHELL去执行这个脚本。
- 如果#!指定的解释程序不存在,那么会报错“bad interpreter: No such file or directory”。注意:#!之后的解释程序,需要写其绝对路径(如:#!/bin/bash),它是不会自动到$PATH中寻找解释器的。
- 当然,如果你使用类似于”bash test.sh”这样的命令来执行脚本,那么#!这一行将会被忽略掉,解释器当然是用命令行中显式指定的bash。
- 脚本文件必须拥有可执行权限。
Shebang的好处在于,允许脚本和数据文件充当系统命令,无需在调用时由用户指定解释器,从而对用户和其它程序隐藏其实现细节。下面我们一起来看几个典型的例子:
#!/bin/sh:使用 sh,即 Bourne shell 或其它兼容 shell 执行脚本
#!/bin/csh:使用 csh,即 C shell 执行
#!/usr/bin/perl -w:使用带警告的 Perl 执行
#!/usr/bin/python -O:使用具有代码优化的 Python 执行
#!/usr/bin/php:使用 PHP 的命令行解释器执行