shell 脚本入门

shell 是一个用 C 编写的程序,既是一种命令语言,又是一种程序设计语言,常用于运行自动化执行 Unix/Linux 系统命令的脚本。在最近的数据收集等任务当中,发现其实对于脚本的使用其实有着较大的需求,之前我都是直接用 Python 写脚本来完成,效果也不错,但总感觉总有点杀鸡用牛刀的感觉,而且对于系统命令的执行也比较不方便。写过几个自动化提交代码的 shell 脚本,但还是不太熟悉,于是打算找个教程过一遍 shell 脚本编程,算是入门了。

执行

创建 shell 脚本文件,以后缀 .sh 结尾,就可以

  • 直接通过执行文件的方式执行脚本 ./script.sh
  • 通过 sh 命令的方式 sh script.sh 执行

变量

  • shell 中的变量只有两种,分别为数字和字符串,数组。
  • shell 变量命名由字母,数字,下划线组成
  • 通过反引号 ` 可以执行命令,将结果作为返回值赋予变量

操作

  • 赋值
    • 变量直接通过 = 号进行 var=125
    • 通过语句赋值,如 for 循环语句 for file in $(ls /etc)
  • 只读:通过设置 readonly var
  • 删除:unset var
  • 使用:通过在变量前使用 $ 则可
  • 字符串拼接:可以通过 字符串变量字符串 的方式进行拼接

字符串

  • 单引号:不转义原样输出,变量也无效,可以通过成对出现来拼接
  • 双引号:可以有变量,可以有转义字符
  • 可以通过 $# 获取长度
  • 可以通过 ${var:1:3} 的方式进行切片

数组

  • 由括号括住,元素通过空格分隔 arr=(var1 var2 var3)
  • 通过下标 [] 获取元素
  • 使用 @ 可以获取所有元素
  • 通过 # 可以获取数组的长度 {{"${#arr[@]}"}}

通用变量

  • 命令行参数
    • $n 表示第n个参数
    • $# 参数个数
    • $* 所有参数以单个字符串的方式返回
    • $$ 当前进程ID
    • $@ 所有参数以字符串的方式逐个返回

运算符

bash 原生并不支持数学运算,需要通过其它命令来实现,如 expr

  • 算术运算符
    • 加减乘除取余赋值。乘法需要转义 *
    • 相等与不相等:比较数字
  • 关系运算符
    • -eq -ne -gt -lt -ge -le 等于 不等于 大于 小于 大于等于 小于等于
  • 布尔运算符
    • ! -o -a 取反 或 与
  • 逻辑运算符
    • && || 与 或
  • 字符串运算符
    • = != -z -n $ 等于 不等于 长度为0 长度不为0 是否空字符串
  • 文件测试运算符
    • -b -c -d -f -p 是否块设备 字符设备 目录 普通文件 管道
    • -r -w -x -s -e 文件是否可读 可写 可执行 为空 是否存在

命令

  • echo:字符串输出
  • read:从标准输入读取一行
  • printf:与C的类似,进行格式化输出
    • 转义序列:\b \c \n \t 后退 不换行 换行 制表符
  • test:检查条件是否成立
    • test bool-expr = [bool-expr]
  • $[a+b]:执行基本的算数运算,符合两边不能有空格

控制逻辑

if

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
if condition
then
    commands
fi

if condition
then
    commands
else
    commands
fi

if condition
then
    commands
elif condition
then
    commands
fi

for

1
2
3
4
for var in item1 item2 item3
do
    commands
done

in后除了可以跟元素序列,还可以接一个返回多个元素的命令

while

1
2
3
4
5
6
7
while condition
do
    command
done

# infinite loop
while true / while :

case

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
case var in
    1)
        command
        ;;
    2)
        command
        ;;
    *) #其余情况
        command
        ;;
esac

break/contine

跳出循环与跳到下次循环

函数

1
2
3
4
5
6
7
8
9
# 定义
func(){
    commands
    echo "使用参数时通过 $1 调用"
    return '也可以没有返回'
}

# 调用(不需要括号
func

重定向

  • command > file 输出重定向
  • command >> file 追加方式输出重定向

导入 shell 脚本

通过 . filenamesource filename 的方式导入脚本中的变量或函数

Unix/Linux 命令

shell 脚本最强大的功能,还是在于能在脚本中自动化地使用对于系统命令的调用,而其中主要是 Linux 的命令使用,这些就需要额外的学习了,不在此处展开。