本文主要介绍了Linux Shell脚本相关知识,包含以下内容:
1.变量。
2.默认变量。
3.shift操作。
4.条件判断if语句。
5.分支判断case语句。
6.函数。
7.循环while。
8.循环until。
9.循环for。
10.脚本语法检查。
1. 变量
声明变量
字符串变量:
declare A="123456"
数值变量:
$declare -i a=10
declare -i b=3
declare -i c=${a}*${b}
从标准输入读取变量
cat 2.sh
#!/bin/bash
read -p "your first name:" firstname
read -p "your last name:" lastname
echo -e "\full name is :${firstname} ${lastname} !!!"
执行如下:
./2.sh
your first name:abc
your last name:def
ull name is :abc def !!!
2. 默认变量
在脚本中,使用$0, $1, $2, ....来表示执行脚本时所传递的参数. 其中$0表示脚本本身, $1表示第1个参数, $2表示第2个参数.
$#表示从$1开始的参数的个数.
$@表示将"$1", "$2" ,...用空格分隔开的一个列表,每一项是一个字符串.$@表示"$1" "$2" "$3" .....
$*表示将$1,$2,..用空格分隔开的一个字符串,只有一个字符串. $*表示"$1 $2 $3 ...."
现有如下脚本:
cat 8.sh
#!/bin/bash
echo -e "script filename: $0"
echo -e "argument count: $#"
echo -e "arguments:$1,$2,$3,$4,$5,$6,$7,$8,$9,$10"
echo -e "$""@:$@"
echo -e "$""*:$*"
执行结果如下:
source 8.sh a1 a2 a3 a4 a5 a6 a7 a8 a9
script filename: bash
argument count: 9
arguments:a1,a2,a3,a4,a5,a6,a7,a8,a9,a10
$@:a1 a2 a3 a4 a5 a6 a7 a8 a9
$*:a1 a2 a3 a4 a5 a6 a7 a8 a9
$$表示当前进程的进程ID.
[oracle@102.coe2coe.me:~/test/bash]$echo $$
3581
[oracle@102.coe2coe.me:~/test/bash]$ps -elf|grep 3581
0 S oracle 3581 3574 0 80 0 - 7054 wait 09:22 pts/14 00:00:00 bash
0 R oracle 7101 3581 0 80 0 - 5828 - 10:54 pts/14 00:00:00 ps -elf
0 S oracle 7102 3581 0 80 0 - 4156 pipe_w 10:54 pts/14 00:00:00 grep --color=auto 3581
$@和$*的区别使用以下脚本可以方便的看到:
cat 8.sh
#!/bin/bash
echo -e "PID:$$"
echo -e "script filename: $0"
echo -e "argument count: $#"
echo -e "arguments:$1,$2,$3,$4,$5,$6,$7,$8,$9,$10"
echo -e "$""@:$@"
echo -e "$""*:$*"
echo -e "-----------\$@-------------"
for i in "$@"; do
echo -e "$i"
done
echo -e "-----------\$*---------------"
for i in "$*"; do
echo -e "$i"
done
[oracle@102.coe2coe.me:~/test/bash]$./8.sh a1 a2 a3 a4 a5
PID:7414
script filename: ./8.sh
argument count: 5
arguments:a1,a2,a3,a4,a5,,,,,a10
$@:a1 a2 a3 a4 a5
$*:a1 a2 a3 a4 a5
-----------$@-------------
a1
a2
a3
a4
a5
-----------$*---------------
a1 a2 a3 a4 a5
3. shift操作
shift操作可以将$1,$2,$3,$4,$5等参数列表中的第1个元素从列表中移除.使得参数列表变成为$2,$3,$4,$5.参数的个数也减少一个.
./10.sh a1 a2 a3 a4 a5
PID:7502
script filename: ./10.sh
argument count: 5
arguments:a1,a2,a3,a4,a5,,,,,a10
$@:a1 a2 a3 a4 a5
$*:a1 a2 a3 a4 a5
-----------$@-------------
a1
a2
a3
a4
a5
-----------$*---------------
a1 a2 a3 a4 a5
shift ..... //第1次shift操作之后,参数列表变为$2,$3,$4,$5
-----------$@-------------
a2
a3
a4
a5
-----------$*---------------
a2 a3 a4 a5
shift ..... //第2次shift操作之后,参数列表变为$3,$4,$5.
-----------$@-------------
a3
a4
a5
-----------$*---------------
a3 a4 a5
shift还可以带参数,表示将几个参数从参数列表中移除掉.
shift 2 表示移除掉最前面的2个参数.
默认为1,即移除掉最前面的1个参数.
4. 条件判断if语句
条件判断使用test命令或者中括号[]来进行.
if [ 条件判断表达式 ]; then
其他语句
fi
当then和if条件在同一行时,必须使用分号(;).
当then和if条件不在同一行时,可以省略分号(;),也可以不省略分号.
if [ 条件判断表达式 ]
then
其他语句
fi
cat 11.sh
#!/bin/bash
echo "argument count:$#"
echo "arguments:$@"
if [ "$#" -lt 1 ]; then
echo -e "too small arguments. argument count must be greater then 0 "
fi
没有参数的情况,if条件满足了.
source 11.sh
argument count:0
arguments:
too small arguments. argument count must be greater then 0
带有2个参数的情况,if条件不满足.
[oracle@102.coe2coe.me:~/test/bash]$source 11.sh a1 a2
argument count:2
arguments:a1 a2
if语句中的条件表达式可以有多个,此时可用&&或者||来表示逻辑与和逻辑或的关系.
cat 12.sh
#!/bin/bash
echo "argument count:$#"
echo "arguments:$@"
if [ "$#" -gt 0 ] && [ "$1" -gt 10 ] && [ "$1" -lt 20 ]; then
echo -e "condition matches."
fi
[oracle@102.coe2coe.me:~/test/bash]$./12.sh 12
argument count:1
arguments:12
condition matches.
[oracle@102.coe2coe.me:~/test/bash]$./12.sh 9
argument count:1
arguments:9
上述脚本中的带有&&逻辑与运算符的if表达式等效于以下脚本中的带-a 参数的表达式.
而带||逻辑或运算符号的表达式等效于-o参数的表达式.
cat 13.sh
#!/bin/bash
echo "argument count:$#"
echo "arguments:$@"
if [ "$#" -gt 0 -a "$1" -gt 10 -a "$1" -lt 20 ]; then
echo -e "condition matches."
fi
[oracle@102.coe2coe.me:~/test/bash]$./13.sh 13
argument count:1
arguments:13
condition matches.
[oracle@102.coe2coe.me:~/test/bash]$./13.sh 21
argument count:1
arguments:21
复杂的条件判断可以使用以下语法来实现:
if [ 条件表达式1 ]; then
执行语句1
elif [ 条件表达式2 ]; then
执行语句2
else
执行语句3
fi
cat 14.sh
#!/bin/bash
echo "argument count:$#"
echo "arguments:$@"
if [ "$#" -lt 1 ]; then
echo -e "argument count too small."
exit -1;
elif [ "$1" -lt 60 ]; then
echo -e "bad"
elif [ "$1" -lt 80 ]; then
echo -e "good"
elif [ "$1" -le 100 ]; then
echo -e "excellent"
else
echo -e "abnormal"
fi
./14.sh 30
argument count:1
arguments:30
bad
[oracle@102.coe2coe.me:~/test/bash]$./14.sh 70
argument count:1
arguments:70
good
[oracle@102.coe2coe.me:~/test/bash]$./14.sh 90
argument count:1
arguments:90
excellent
[oracle@102.coe2coe.me:~/test/bash]$./14.sh 120
argument count:1
arguments:120
abnormal
5. 分支判断case语句
case语句的语法格式如下所示:
case "变量名称" in
"变量的值" 1)
语句1
;;
"变量的值" 2)
语句2
;;
*)
语句3
;;
esac
每个分支的值后面必须有小括号分隔开.每个分支的最后面必须有2个连续的分号(;)来隔开. 最后一个分支一般使用*)表示其它值. 语句的最后使用esac关键字结束语句.
cat 15.sh
#!/bin/bash
echo "argument count:$#"
echo "arguments:$@"
if [ "$#" -le 0 ]; then
echo -e "too small argument count"
exit -1
fi
case "$1" in
"a")
echo -e "excellent"
;;
"b")
echo -e "good"
;;
"c")
echo -e "bad"
;;
*)
echo -e "abnormal"
;;
esac
./15.sh
argument count:0
arguments:
too small argument count
[oracle@102.coe2coe.me:~/test/bash]$./15.sh a
argument count:1
arguments:a
excellent
[oracle@102.coe2coe.me:~/test/bash]$./15.sh b
argument count:1
arguments:b
good
[oracle@102.coe2coe.me:~/test/bash]$./15.sh c
argument count:1
arguments:c
bad
[oracle@102.coe2coe.me:~/test/bash]$./15.sh d
argument count:1
arguments:d
abnormal
[oracle@102.coe2coe.me:~/test/bash]$./15.sh abc
argument count:1
arguments:abc
abnormal
6. 函数
bash脚本中可以定义和调用函数.
函数的参数的访问也是使用$#,$@,$*,$1,$2等等来实现. 函数的返回值使用return语句来定义,在调用函数时使用$?来取得函数的返回值.
cat 16.sh
#!/bin/bash
function evaluate_score( ) {
case "$1" in
"a")
echo -e "excellent"
return 5
;;
"b")
echo -e "good"
return 3
;;
"c")
echo -e "bad"
return 1
;;
*)
echo -e "abnormal"
return 0
;;
esac
}
echo "argument count:$#"
echo "arguments:$@"
if [ "$#" -le 0 ]; then
echo -e "too small argument count"
exit -1
fi
evaluate_score "$1"
echo "function return value:$?"
[oracle@102.coe2coe.me:~/test/bash]$./16.sh a
argument count:1
arguments:a
excellent
function return value:5
[oracle@102.coe2coe.me:~/test/bash]$./16.sh b
argument count:1
arguments:b
good
function return value:3
[oracle@102.coe2coe.me:~/test/bash]$./16.sh c
argument count:1
arguments:c
bad
function return value:1
[oracle@102.coe2coe.me:~/test/bash]$./16.sh d
argument count:1
arguments:d
abnormal
function return value:0
[oracle@102.coe2coe.me:~/test/bash]$./16.sh
argument count:0
arguments:
too small argument count
7. 循环while
while循环的语法如下:
while [ 条件 ];
do
语句;
done
当条件满足时,继续执行循环,否则退出循环.
cat 17.sh
#!/bin/bash
echo -e "argument count:${#}";
echo -e "arguments:${@}";
function test_while() {
local i=0;
while [ ${i} -lt $# ];
do
echo -e "${i}";
let i=i+1;
done
}
echo -e "----------------------"
test_while $1 $2 $3
echo -e "-----------------------------"
test_while $@
source 17.sh a b c
argument count:3
arguments:a b c
----------------------
0
1
2
-----------------------------
0
1
2
8. 循环until
until循环的语法如下:
until [ 条件 ];
do
语句;
done
当不满足条件时,执行循环,否则退出循环.
cat 18.sh
#!/bin/bash
echo -e "argument count:${#}";
echo -e "arguments:${@}";
function test_until() {
local i=0;
until [ ${i} -ge $# ];
do
echo -e "${i}";
let i=i+1;
done
}
echo -e "----------------------"
test_until "$1" "$2" "$3" "$4"
echo -e "-----------------------------"
test_until $@
echo -e "---------------"
test_until $*
source 18.sh a b c "aa bb cc"
argument count:4
arguments:a b c aa bb cc
----------------------
0
1
2
3
-----------------------------
0
1
2
3
4
5
---------------
0
1
2
3
4
5
9. 循环for
for循环的语法如下:
for 循环变量 in 集合变量
do
语句;
done
在循环体中使用${循环变量}的方式访问循环变量.for循环中的循环变量为全局变量,在循环体之外,以及循环所在函数之外均可以正常访问.
cat 20.sh
#!/bin/bash
echo -e "argument count:${#}";
echo -e "arguments:${@}";
function test_for() {
for i in $@
do
echo -e "${i}";
done
}
echo -e "----------------------"
test_for $1 $2 $3
echo -e "-----------------------------"
test_for $@
echo "i is : ${i} ."
source 20.sh a b c "aa bb cc"
argument count:4
arguments:a b c aa bb cc
----------------------
a
b
c
-----------------------------
a
b
c
aa
bb
cc
i is : cc .
for循环还可以方便的访问集合中的元素.语法如下:
for 循环变量 in $(seq 最小值 最大值)
do
语句;
done
其中$(seq 最小值 最大值)表示一个集合,元素为最小值到最大值之间的连续的整数.
还可以表示为:
for 循环变量 in {最小值..最大值}
do
语句;
done
其中{最小值..最大值}表示的含义跟$(seq 最小值 最大值)相同.
cat 21.sh
#!/bin/bash
for i in $(seq 1 5)
do
echo -e "${i}";
done
echo -e "---------------"
for i in {1..5}
do
echo -e "${i}"
done
[oracle@102.coe2coe.me:~/test/bash]$source 21.sh
1
2
3
4
5
---------------
1
2
3
4
5
这里介绍的连续整数的集合的变量形式,不仅适用于for循环,还可以用于其它语句中.
echo $(seq 1 6)
1 2 3 4 5 6
[oracle@102.coe2coe.me:~/test/bash]$echo {1..6}
1 2 3 4 5 6
for循环还可以按照初值和步长的方式来定义一个循环.
for ((循环变量初值; 条件; 变化))
do
语句;
done
此时,for关键后的表达式必须使用两个小括号括起来:(()).
cat 22.sh
#!/bin/bash
for (( i=1; i<=5; i=i+1))
do
echo "${i}"
done
[oracle@102.coe2coe.me:~/test/bash]$source 22.sh
1
2
3
4
5
10. 脚本语法检查
sh命令使用-n参数表示不执行脚本,而是仅仅检查脚本有误语法错误.
现在有一个存在语法错误的脚本的内容如下:
cat 23.sh
#!/bin/bash
echo -e "this script is for test only."
#此处存在一个语法错误.
echo -e "aaaaa'
for ((i=1; i<=5; i=i+1))
do
echo "${i}"
done
直接使用source方式执行脚本时,会先执行存在语法错误之前的各个语句,比如echo.
[oracle@102.coe2coe.me:~/test/bash]$source 23.sh
this script is for test only.
bash: 23.sh: line 9: unexpected EOF while looking for matching `"'
bash: 23.sh: line 12: syntax error: unexpected end of file
使用sh -n方式检查脚本语法错误时,并不会实际执行任何语句.
[oracle@102.coe2coe.me:~/test/bash]$sh -n 23.sh
23.sh: 12: 23.sh: Syntax error: Unterminated quoted string