Shell and Shell Scripts

Shell

在Linux中有很多Shell可以使用,常用的有如下:

  • sh:即Bourne shell,由Steven Bourne开发,这是第一个流行的shell
  • bash:即Bourne Again Shell,由GNU组织开发,属于Bourne shell的增强版本,这是Linux默认使用的shell
  • csh:即C shell,由Bill Joy开发,这是流行于学术界Sun主机的shell

虽然shell有很多种,但是学习和工作都是基于Linux,所以掌握bash即可。

bash的功能

  • 历史命令记录(history)
  • 命令补全功能(bash-completion)
  • 命令别名设置(alias)
  • shell脚本执行(shell scripts)

bash的命令分类

在bash中执行的命令分为两种类型:

  • 内置命令:内置命令是指集成在bash里面的可以执行的文件,例如:cd、pwd

  • 外部命令:外部命令是文件系统里的可执行文件,例如用户下载的软件和编写的脚本文件

如何在bash中判断命令的类型?type target-command

如果target-command是一个内置命令,则会打印如下信息:

1
target-command is a shell builtin

注意:使用时,将target-command替换具体的命令,例如:cd、ls

那么如果知道当前使用的shell类型和支持哪些shell类型呢?

  • 当前支持的shell类型

    1
    2
    3
    $ echo $SHELL
    /bin/sh

  • 当前使用的shell类型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $ cat /etc/shells 
    # /etc/shells: valid login shells
    /bin/sh
    /bin/bash
    /usr/bin/bash
    /bin/rbash
    /usr/bin/rbash
    /usr/bin/sh
    /bin/dash
    /usr/bin/dash

其实在创建用户时就会指定一种要使用的shell类型:

1
2
3
4
5
6
7
8
9
$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
user:x:1000:1000:user,,,:/home/caojun:/bin/bash
ubuntu:x:1000:1000:ubuntu,,,:/home/caojun:/bin/sh

root用户就是使用shell类型就是:bash,而ubuntu用户使用的shell类型是:sh

bash的技巧

在使用bash中有很多常用的小技巧或者小功能,有必要学习和记录一下。

  • 命令换行:输入一行命令太长,阅读效果并不好,需要拆分成多行显示。在需要换行位置输入 \ ,紧接着按下回车键(Enter),然后接着输入未完成的命令。
  • 光标跳转:输入一行命令后,发现行头附近有错误或者行尾处有错误,需要快速跳转到行头或行尾。通过组合键进行光标快速跳转,Ctrl+A 调到行头,Ctrl+E 跳到行尾
  • 环境变量:bash中有很多默认的环境变量,所以很多部命令不需要输入绝对路径就可以执行。通过 env 可以查询所有的默认环境变量。

Shell Scripts

shell scripts是什么?

shell script是利用shell的功能所写的一个“程序(program)”,这个程序是使用纯文本文件,将一些shell的语法与指令(包含外部指令)写在里面,搭配正则表达式、管道命令与数据重定向等功能,以达到我们所想要的处理目的。

变量

变量一般用于存放数据,而且可以支持修改,方便在不同环境执行时,仅仅修改变量即可使用。

变量名的限制:

  • 变量名和等号之间不能有空格(语法规定)

  • 变量名只能由字母(a~zA~Z)、数字(0~9)、下划线(_)组成,且不能以数字开头

  • 变量名不能使用shell中的关键字

简单示例1:

1
2
3
4
5
6
7
#!/bin/bash

# a simple example, print string "hello world"
str1='hello'
str2="world"

echo $str1 ${str2}

注意:定义变量时,直接给变量赋值。使用变量时,必须通过$符号引用,而且建议用{}将变量包含起来。

判断

判断语句一般用于检查条件符合什么条件,然后执行相应的内容。

if判断语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/bin/bash

# condition check, if [...];then

target_file=condition.sh
target_str=hello

# example 1
if [ -e ${target_file} ];then
echo ${target_file} exist
fi

# example 2
if [ ${target_str} == "hello" ];then
echo ${target_str} is exist
else
echo ${target_str} is not exit
fi

# example 3
if [ $1=='1' ];then
echo "1"
elif [ $1=='2' ];then
echo "2"
else
echo "other"
fi

注意:

1、第一行 #!/bin/bash 表示该脚本文件使用shell类型是:bash,脚本文件内部的命令使用bash语句进行解释。

2$1 表示传入第一个参数。

文件测试标志:

  • -e:检查目标文件是否存在
  • -f:检查目标文件是否存则且为普通文件
  • -d:检查目标文件是否存在且文件类型是目录

整数之间的比较:

  • -eq:相等
  • -ne:不相等
  • -gt:大于
  • -lt:小于
  • -ge:大于等于
  • -le:小于等于

字符串之间的比较:

  • ==:字符串相同
  • !=:字符串不同
  • -z:字符串长度是否为0
  • -n:字符串长度是否为非0

case判断语句

通过传入的数字字符串来判断星期几

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/bin/bash

# print weekday by a number
option=$1
case ${option} in
1)
echo "Mon"
;;
2)
echo "Tue"
;;
3)
echo "Wed"
;;
4)
echo "Thu"
;;
5)
echo "Fri"
;;
6)
echo "Sat"
;;
7)
echo "Sun"
;;
*)
echo "unkonwn"
;;
esac

循环

执行循环体,打印从1到10

1
2
3
4
5
6
7
#!/bin/bash

for i in $(seq 1 10)
do
echo $i
done

函数

将固定的功能模块化–函数,之后可以复用该函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/bash

function printit() {
echo -n "Your choice is "
}

echo "This program will print your selection!"
case ${1} in
"one")
printit; echo ${1} | tr 'a-z' 'A-Z'
;;
"two")
printit; echo ${1} | tr 'a-z' 'A-Z'
;;
"three")
printit; echo ${1} | tr 'a-z' 'A-Z'
;;
*)
echo "Usage ${0} {one;two;three}"
;;
esac