简易 shell 脚本入门 (纯示例代码)

经常会遇到需要简单编写 shell 脚本的情况, 每次都忘记 shell 脚本语法然后去查资料.
故专门写篇文章记录常用的 shell 语法.

如何运行 shell 脚本

[root@host shell]# vim start
[root@host shell]# cat start
#!/bin/bash
echo 'hello'
[root@host shell]# chmod 755 start
[root@host shell]# ./start hello

数据类型

字符串

a=1
a=1+1 # 这是字符串 '1+1'

整数

a=$(( 1+1 ))

数组

# 初始化
a[2]=100
a=(2 4 'str' 4)
a=([0]=2 [2]='str' [4]=20)

# 单个赋值
a[2]='s'

# 打印整个数组
echo ${a[@]}

# 遍历数组
for i in ${a[@]}; do
  echo $i
done

# 数组元素个数
echo ${#a[@]}

# 指定下标添加元素
a=([0]=2 [2]='str')
a[3]=1
a[6]=6

# 删除整个数组
unset a

# 删除数组内单个元素
unset a[1]

变量

# 声明字符串变量
title='hello'
num=1  # 这个也是字符串

# 声明整数变量
num=$((1))

注意: 等号 = 左右不能有空格

表达式

# $(expression)

a=$(date)
a=$(ls ~)

echo ${a}

控制流

if

a=5
if [ $a = 5 ]; then
  echo 'a = 5'
else
  echo 'a != 5'
fi

while

count=1
while (( count < 5 )); do
  echo $count
  count=$((count + 1))
done
echo 'finish'

for

for i in {a..d}; do
  echo $i
done

# 输出 a b c d
for (( i=0; i<5; i++ )); do
  echo $i
done

# 输出 0 1 2 3 4

switch case

case 语句比较复杂, 语法为

case word in
    [pattern [| pattern]...) commands ;;]...
esac

例子:

a=1
case $a in
  0) echo '1';;
  1) echo '2';;
  *) echo '*';;
esac  # case 逆序

# 2

常用表达式

在控制流的逻辑真假判断表达式中, 可以替换为其他表达式, 比如下面的这些常用表达式

判断文件表达式

[ -e file ]  # file 存在

[ -d file ]  # file 是一个目录
[ -f file ]  # file 存在并且是一个普通文件

[ -r file ]  # file 存在并且可读
[ -w file ]  # file 存在并且可写
[ -x file ]  # file 存在并且可执行

字符串表达式

[ string ]  # string 不为 null
[ -n string ]  # string 长度大于 0
[ -z string ]  # string 长度等于 0

[ string1 == string2 ]  # string1 和 string2 相同
[ string1 != string2 ]
[ string1 > string2 ]  # string1 排列在 string2 之后, 比较字符编码大小
[ string1 < string2 ]  # < > 在 test 下须用引号括起

整数表达式

[ int1 -eq int2]  # int1 等于 int2
[ int1 -ne int2]  # int1 不等于 int2
[ int1 -le int2]  # int1 小于或等于 int2
[ int1 -lt int2]  # int1 小于 int2
[ int1 -ge int2]  # int1 大于或等于 int2
[ int1 -gt int2]  # int1 大于 int2

注意: 整数表达式更喜欢用另一个复合符号: (( ))

复合符号

[[ ]]

该复合符号拥有 [ ] 的能力, 且多了正则表达式的能力

# 例子1
a='a'
if [[ $a =~ . ]]; then
  echo 'a'
fi

# 例子2
a=123
if [[ $a =~ ^[0-9]+? ]]; then
  echo 'a'
fi

(( ))

该复合符号, 主要用于更直观的操作整数

a=123
if (( $a > 100 )); then
  echo 'a'
fi

多个表达式之间可以带逻辑操作符

[[ expression1 && expression2 ]]  # 表达式之间进行与操作, 短路操作符
[[ expression1 || expression2 ]]  # 表达式之间进行或操作, 短路操作符
[[ !expression ]]

函数

无参函数

name() {
  echo 'name'
}

name  # 调用

含参函数

say() {
  echo $1
  echo $2
}

say helo lo

与命令行传参取值类似

命令行参数

echo $1
echo $2

# 在命令行输入, 其中 $1 为 hello 字符串, $2 为 world 字符串
./shell hello world

参考

TLCL: http://billie66.github.io/TLCL/book/index.html

下一篇博客会列举我在学习 shell 脚本时的一些疑惑与解答.

(如有错误或不同的见解, 望不吝指出, 愿共同进步!)

相关推荐