一、什么是shell?

我们平时所说的 Shell 可以理解为 Linux 系统提供给用户的使用界面。Shell 为用户提供了输入命令和参数并可得到命令执行结果的环境。当一个用户登录 Linux 之后,系统初始化程序 init 就根据 /etc/passwd 文件中的设定,为每个用户运行一个被称为 Shell(外壳)的程序。

确切地说,Shell 是一个命令行解释器,它为用户提供了一个向 Linux 内核发送请求以便运行程序的界面系统级程序,用户可以用 Shell 来启动、挂起、停止甚至编写一些程序。


二、什么是shell脚本?

与一般命令相比,Shell 除了是一个命令行解释器,同时还是一门功能强大的编程语言,易编写,易调试,灵活性较强。作为一种命令级语言,Shell 是解释性的,组合功能很强,与操作系统有密切的关系,可以在 Shell 脚本中直接使用系统命令。大多数 Linux 系统的启动相关文件(一般在 /etc/rc.d 目录下)都是使用 Shell 脚本编写的。

同传统的编程语言一样,Shell 提供了很多特性,这些特性可以使 Shell 脚本编程更为有用,如数据变量、参数传递、判断、流程控制、数据输入和输出、子程序及中断处理等。


三、Shell的分类

Shell 编程跟 java、php 编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。Linux 的 Shell 种类众多,常见的有:

  • Bourne Shell(/usr/bin/sh或/bin/sh)
    是UNIX最初使用的 shell,而且在每种 UNIX 上都可以使用。Bourne Shell 在 shell 编程方面相当优秀,但在处理与用户的交互方面做得不如其他几种 shell。
  • Bourne Again Shell(/bin/bash)
    Linux默认的脚本种类,它是 Bourne Shell 的扩展。 与 Bourne Shell 完全兼容,并且在 Bourne Shell 的基础上增加了很多特性,可以提供命令补全,命令编辑和命令历史等功能。
  • C Shell(/usr/bin/csh)
    是一种比 Bourne Shell更适合的变种 Shell,它的语法与 C 语言很相似。
  • K Shell(/usr/bin/ksh)
    集合了 C Shell 和 Bourne Shell 的优点并且和 Bourne Shell 完全兼容。

这里演示用的是 Bash,也就是 Bourne Again Shell,由于易用和免费,Bash 在日常工作中被广泛使用。同时,Bash 也是大多数Linux 系统默认的 Shell。

在一般情况下,人们并不区分 Bourne Shell 和 Bourne Again Shell,所以,像 #!/bin/sh,它同样也可以改为 #!/bin/bash


我们可以通过 /etc/shells 文件来査询 Linux 支持的 Shell。命令如下:

$ cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/bin/tcsh
/bin/csh

用户信息文件 /etc/passwd 的最后一列就是这个用户的登录 Shell。命令如下:

$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x: 1:1 :bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
...

可以看到,root 用户和其他可以登录系统的普通用户的登录 Shell 都是 /bin/bash,也就是 Linux 的标准 Shell,所以这些用户登录之后可以执行权限允许范围内的所有命令。不过,所有的系统用户(伪用户)因为登录 Shell 是 /sbin/ndogin,所以不能登录系统。


四、第一个shell脚本

打开文本编辑器(可以使用 vi/vim 命令来创建文件),新建一个文件 test.sh,扩展名为 sh(sh代表shell),内容如下所示:

#!/bin/bash
echo "Hello World !"

#! 告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序。运行该脚本,打印命令 echo 会在屏幕上打印出后面的字符串。


五、运行Shell脚本的两种方法

1、作为可执行程序

第一种运行方式是,先使前面的test.sh脚本具有执行权限,然后像运行其它二进制程序一样执行脚本即可:

chmod +x ./test.sh  #使脚本具有执行权限
./test.sh  #执行脚本

注意,一定要写成 ./test.sh,而不是 test.sh,直接写 test.sh,linux 系统会去 PATH 里寻找有没有叫 test.sh 的,而只有 /bin, /sbin, /usr/bin,/usr/sbin 等在 PATH 里,你的当前目录通常不在 PATH 里,所以写成 test.sh 是会找不到命令的,要用 ./test.sh 告诉系统说,就在当前目录找。


2、作为解释器参数

第二种运行方式是,直接运行解释器,其参数就是 shell 脚本的文件名,如:

/bin/sh test.sh

这种方式运行的脚本,不需要在第一行指定解释器信息,写了也没用。


六、Shell注释

1、单行注释

# 开头的行就是注释,会被解释器忽略,像这样

#--------------------------------------------
# 这是一个注释
# author:feng
#--------------------------------------------
##### 用户配置区 开始 #####
#
# 这里可以添加脚本描述信息
# 
##### 用户配置区 结束  #####

如果在开发过程中,遇到大段的代码需要临时注释起来,过一会儿又取消注释,怎么办呢?

每一行加个#符号太费力了,可以把这一段要注释的代码用一对花括号括起来,定义成一个函数,不调用这个函数,就不会执行这块代码,达到了和注释一样的效果。


2、多行注释

多行注释还可以使用以下格式:

:<<EOF
注释内容...
注释内容...
注释内容...
EOF

EOF 也可以使用其他符号:

:<<'
注释内容...
注释内容...
注释内容...
'

:<<!
注释内容...
注释内容...
注释内容...
!


参考:

Shell 教程

Shell脚本是什么