看到这篇文章,默认你对 shell 有一定的了解,原理性的内容就不在啰嗦,直接介绍 shell 脚本编程。
1. Shell 脚本创建与执行
1.1 Shell 脚本创建
可以使用 touch 或者 vim 来创建一个 shell 脚本文件。
$ touch test1.sh
$ vim test2.sh
Shell 脚本的第一行内容在首行左侧,表示脚本要调用的 shell 解释器,内容如下:
#!/bin/bash
例如以下一个可运行的 shell 脚本:
#!/bin/bash
echo "This is a demo!"
1.2 Shell 脚本运行
运行 shell 脚本,需要脚本文件有可执行权限,修改脚本权限:
$ chmod +x test.sh
执行脚本有 3 种方式:
a. 绝对路径或相对路径
$ /temp/test.sh
$ ./test.sh
b. sh + 脚本
$ sh test.sh
c. 路径前加 “.” 或者 “source”
$ . ./test.sh # 为了区别与路径符号,两个 "." 之间加一个空格
$ source test.sh
其中,前两种方式会新开一个 bash 来执行脚本,不同的 bash 无法共享变量(主要是环境变量);第三种方式是在同一个 bash 中执行脚本,变量可以共享。
在实际工作中,要根据这三种方式的特性来使用,如果不注意,可能会导致意想不到的结果。
2. Shell 编程
2.1 Shell 变量
2.1.1 变量设置规则
- 变量名称可以由字母,数字和下划线组成,但不能以数字开头,环境变量名建议大写;
- 在 bash 中,变量的默认类型都是字符串型,如果要进行数值运算,则必须指定变量类型为数值型;
- 变量用等号连接值,等号左右两侧不能有空格;变量的值如果有空格,需要使用单引号或者双引号包括。
2.1.2 变量赋值
a. 定义时赋值:
VAR="Hello World"
b. 将命令的执行结果赋值给变量
以下两种赋值方式等价。
VAR1=`ls`
VAR2=$(ls)
- $() 只是提取命令执行后的标准输出。
c. 将变量赋值给另一个变量
VAR1="Hello World"
VAR2=$VAR1
VAR3=${VAR1}
2.1.3 变量调用
取变量值时,在变量前加 “$” 前缀,以下两种方式都可以:
$ VAR="Hello World"
$ echo $VAR
Hello World
$ echo ${VAR}
Hello World
- " $ " 和 " ${} " 是等价的,但在需要连接参数时,就必须使用 " ${} "。
如下:
VAR1="CONFIG_${VAR}_ENABLE"
单引号、双引号和反引号的区别
- 单引号:所见即所得,输出时会将单引号内的所有内容都原样输出,不会解析变量值,称为强引用。
- 双引号:输出双引号的所有内容;如果其中有命令(要反引号)、变量、特殊转义,会先把变量、命令、转义字符解析出结果,然后在输出最终内容,称为弱引用。
- 反引号:一般用于命令,执行的时候命令会被执行,相当于 $(),赋值和输出都要用反引号引起来。
2.1.4 环境变量
用户自定义变量只在当前 shell 生效,而环境变量会在当前 shell 和该 shell 的所有子 shell (子 shell 必须是 “.” 或 “source” 来启动)中生效。
export <环境变量名>=<变量值>
2.1.5 数组
Shell 的数组格式如下:
array_name=(value1 ... valuen)
数组取值:
${array_name[0]}
${array_name[1]}
${array_name[2]}
2.1.6 运算符
数值运算符:
| 运算符 | 说明 |
|---|---|
| -eq | 判断两个数是否相等,相等返回 true;[ $a -eq $b ] |
| -ne | 判断两个数是否不相等,不相等返回 true;[ $a -ne $b ] |
| -gt | 判断左边的数是否大于右边的,如果是,则返回 true;[ $a -gt $b ] |
| -lt | 判断左边的数是否小于右边的,如果是,则返回 true;[ $a -lt $b ] |
| -ge | 判断左边的数是否大于等于右边的,如果是,则返回 true;[ $a -ge $b ] |
| -le | 判断左边的数是否小于等于右边的,如果是,则返回 true;[ $a -le $b ] |
字符串运算符:
| 运算符 | 说明 |
|---|---|
| = | 判断两个字符串是否相等,相等返回 true;[ $str1 = $str2 ] |
| != | 判断两个字符串是否相等,不相等返回 true;[ $str1 != $str2 ] |
| -z | 判断字符串长度是否为 0,为0返回 true;[ -z $str1 ] |
| -n | 判断字符串长度是否为 0,不为0返回 true;[ -n “$str1” ] |
| $ | 判断字符串是否为空,不为空返回 true;[ $str1 ] |
文件操作符:
| 操作符 | 说明 |
|---|---|
| -d | 判断文件是否是目录,如果是,则返回 true;[ -d $file ] |
| -f | 判断文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true;[ -f $file ] |
| -r | 判断文件是否可读,如果是,则返回 true;[ -r $file ] |
| -w | 判断文件是否可写,如果是,则返回 true;[ -w $file ] |
| -x | 判断文件是否可执行,如果是,则返回 true;[ -x $file ] |
| -s | 判断文件是否为空(文件大小是否大于0),不为空返回 true;[ -s $file ] |
| -e | 判断文件(包括目录)是否存在,如果是,则返回 true;[ -e $file ] |
| -L | 判断文件是否存在并且是一个符号链接,如果是,则返回 true;[ -L $file ] |
2.2 Shell 语法
2.2.1 if-else 语句
if cmd1; then
# Do something
if
if cmd1; then
# Do something
elif cmd2; then
# Do something
else
# Do something
fi
if 语句有以上两种用法,当 cmd1 或 cmd2 为 true 时,就会执行对应的分支。
2.2.2 for 循环
for var in item1 item2 ... itemN
do
# Do something
done
参数列表可以是数值,也可以是字符串。
for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done
# 输出结果:
The value is: 1
The value is: 2
The value is: 3
The value is: 4
The value is: 5
for str in 'Hello World'
do
echo $str
done
# 输出结果:
Hello World
2.2.3 while 语句
while condition
do
# Do something
done
举例如下:
int=1
while (( $int<=3 ))
do
echo $int
let "int++"
done
# 输出结果:
1
2
3
无限循环两种方式:
while true
do
# Do something
done
while :
do
# Do something
done
2.2.4 case 语句
case var in
var1)
# Do something
;;
var2)
# Do something
;;
esac
case 语法如上所示。取值后面必须为单词 in,每一模式必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;; 。
举例如下:
str="ab"
case "$str" in
"ab") echo "ab"
;;
"cd") echo "cd"
;;
"ef") echo "ef"
;;
esac
# 输出为:
ab
2.2.5 函数
函数定义:
function fun_name () {
# Do something
# return ret
}
function fun_name {
# Do something
# return ret
}
- 参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。
函数使用例程如下:
function fun_demo {
echo "This is demo."
return 0
}
# 函数调用
fun_demo
函数带参数例程:
function fun_demo {
echo "1: $1"
echo "2: $2"
echo "10: $10"
echo "All: $#"
}
fun_demo 1 2 3 4 5 6 7 8 9 10 11
# 输出结果:
1: 1
2: 2
10: 10
All: 11
函数参数:
| 参数形式 | 说明 |
|---|---|
| $n | n 为数字,0 代表命令本身,1 - 9 代表第 1 到第 9 个参数,10 以上的参数需要用大括号包含,如 ${10} |
| $* | 代表命令行中所有的参数,把所有的参数看成一个整体。以"12 … $n"的形式输出所有参数 |
| $@ | 代表命令行中的所有参数,把每个参数区分对待,以"1"“2” … “$n” 的形式输出所有参数 |
| $# | 代表命令行中所有参数的个数,添加到shell的参数个数 |
| $? | 执行上一个命令的返回值,执行成功,返回0,执行失败,返回非 0(具体数字由命令决定) |
| $$ | 当前进程的进程号(PID),即当前脚本执行时生成的进程号 |
| $! | 后台运行的最后一个进程的进程号(PID),最近一个被放入后台执行的进程 |
1103

被折叠的 条评论
为什么被折叠?



