本文主要从以下8 个方面介绍Linux下的shell编程:
shell编程是 Linux 下的一门脚本语言——Shell 脚本。这个脚本语言可以帮助我们简化很多工作,例如编写自定义命令等,所以还是很有必要学习它的基本用法的,一个简单的 hello.sh
脚本像下面这样,第一行 #!/bin/bash
标识该 Shell 脚本由哪个 Shell 解释:
#!/bin/bash
echo "Hello World!"
可以有以下两种执行方式:
# 1.直接执行
bash hello.sh
sh hello.sh
# 2.赋予可执行权限后执行
chmod a+x hello.sh
# 执行
./hello.sh
# 结果
Hello World!
Shell 的编写流程:
1. 编写 Shell 脚本
2. 执行
3. 调试
下面来介绍具体的语法
常用的关键字如下:
1. echo:打印文字到屏幕
2. read:读标准输入
3. exec:执行另一个 Shell 脚本
4. expr:对整数型变量进行算术运算
5. test:用于测试变量是否相等、 是否为空、文件类型等
6. exit:退出
例如:
#!/bin/bash
echo "Hello Shell\nInput number:"
# 读入变量
read VAR
echo "VAR is $VAR"
# 计算变量
expr $VAR - 5
# 测试字符串
test "Hello"="HelloWorld"
# 测试整数
test $VAR -eq 10
# 测试目录
test -d ./Android
# 执行其他 Shell 脚本
exec ./othershell.sh
# 退出
exit
运行前,你需要新建一个 othershell.sh
的文件,让它输出 I'm othershell
,并且中途需要一次输入。
运行结果:
Hello Shell
Input number:
10
VAR is 10
5
I'm othershell
学习任何一门语言都要了解它的变量定义方法,Shell 也不例外。
Shell 变量分为 3 种:
1. 用户变量
2. 系统变量
3. 环境变量
定义用户变量需要注意下面 2 点:
1. 等号前后不能有空格:num=10
2. 使用 $+变量名 调用变量
常见有 3 个对用户变量进行操作的前缀:
unset
:删除变量 readonly
:标记只读变量 export
:指定全局变量例如:
#!/bin/bash
# 定义普通变量 str
str=SHENZHEN
# 定义全局变量 name
export name=cdeveloper
# 定义只读变量 num
readonly num=21
# 打印变量的值
echo $str
echo $name
echo $num
# 删除 str 变量
unset str
# 不会输出 SHENZHEN
echo $str
运行结果:
SHENZHEN
cdeveloper
21
常用的系统变量有下面这些:
例如:(example.sh)
#!/bin/bash
echo "print $"
echo "\$0 = $0"
echo "\$1 = $1"
echo "\$2 = $2"
echo "\$# = $#"
echo "\$@ = $@"
echo "\$* = $*"
echo "\$? = $?"
echo "\$$ = $$"
执行./
example.sh 1 2 3 4 5
的结果:
print $
$0 = ./example.sh //程序名
$1 = 1 //第一个参数
$2 = 2 //第二个参数
$# = 5 //命令行参数个数,这里一共5个
$@ = 1 2 3 4 5 //所有命令行参数
$* = 1 2 3 4 5 //所有命令行参数
$? = 0 //之前没有执行其他命令或者函数
$$ = 9450 //进程 ID
Shell 环境变量是所有 shell程序都会接受的一组参数,常用的有下面这几个:
1. HOME:用户主目录
2. PATH:系统环境变量 PATH
3. TERM:当前终端
4. UID:当前用户 ID
5. PWD:当前工作目录,绝对路径
例如:
#!/bin/bash
echo "print ENV"
echo "\$HOME = $HOME"
echo "\$PATH = $PATH"
echo "\$TERM = $TERM"
echo "\$PWD = $PWD"
echo "\$UID = $UID"
运行结果:
print EVN
# 当前主目录
$HOME = /root
# PATH 环境变量
$PATH = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
# 当前终端
$TERM = xterm
# 当前目录
$PWD = /home/linux_shell
# 用户 ID
$UID = 1000
算术比较 | 内容 | 结果 |
expr1 -eq expr2 | == | expr1 与 expr2 相等则结果为真 |
expr1 -ne expr2 | != | expr1 与 expr2 不相等则结果为真 |
expr1 -gt expr2 | > | expr1 大于 expr2 则结果为真 |
expr1 -ge expr2 | >= | expr1 大于或等于 expr2 则结果为真 |
expr1 -lt expr2 | < | expr1 小于 expr2 则结果为真 |
expr1 -le expr2 | <= | expr1 小于或等于 expr2 则结果为真 |
下面是 4 种比较常见的运算方法,功能都是将 m + 1:
1. m=$[ m + 1 ]
2. m=`expr $m+1` #一定要在两边加 ` 符号
3. let m=m+1
4. m=$(( m + 1 ))
例如:
#!/bin/bash
m=1
m=$[ m + 1 ]
echo $m
m=`expr $m+1`
echo $m
# 注意:+ 号左右不要加空格
let m=m+1
echo $m
m=$((m + 1))
echo $m
运行结果:
2
3
4
5
Shell 语句跟高级语言有些类似,也包括分支,跳转,循环等。
shell 的 if 结构为 if then - elif then - else,if 的判断条件主要有两种形式,例如:
#!/bin/bash
echo "Inpu a number:"
read VAR
# 下面这两种判断方法都可以,注意使用
if [ $VAR -lt 10 ] #第一种,[] 左右一定要加空格
then
echo "小于10"
elif test $VAR -eq 10 #第二种
then
echo "等于10"
else
echo "大于10"
fi
case 语句有些复杂,要注意格式:
#!/bin/bash
echo "Input a string:";
read NAME
# 格式有点复杂,一定要注意
case $NAME in
"Linux")
echo "Linux";; #若有多条语句只能在最后一条后面加;;
"Unix")
echo "Unix" ;;
*)
echo "Not Linux or Unix" ;;
esac
运行结果:
root@ubuntu:/home/linux_shell# sh case.sh
Input a string:
Linux
Linux
root@ubuntu:/home/linux_shell# sh case.sh
Input a string:
Unix
Unix
root@ubuntu:/home/linux_shell# sh case.sh
Input a string:
1234
Not Linux or Unix
for 循环有以下两种基本使用方法:(以 do 和 done 表示循环范围)
#!/bin/bash
# 第一种,一定是 (( ))
for ((i = 1; i <= 3; i++))
do
echo $i
done
# 第二种,VAR 依次代表每个元素
for VAR in 4 5 6
do
echo $VAR
done
运行结果:
1
2
3
4
5
6
注意与 for 循环的区别:
#!/bin/bash
echo "请输入一个字符:"
read ch
while [ "1" = "1" ] #while 的死循环
do
case $ch in
"Y")
echo "Right!"
break;;
"N")
echo "Wrong!"
break;;
*)
echo -e "\n输入有误!请重新输入:"
read ch;;
esac
done
运行结果:
root@ubuntu:/home/linux_shell# bash while.sh
请输入一个字符:
t
输入有误!请重新输入:
y
输入有误!请重新输入:
N
Wrong!
until 语句可译为 “直到...的时候”,与上面的循环的不同点是它的结束条件为:判断结果为1时结束
#!/bin/bash
i=1
# 直到 i 等于 5 时,循环结束
until [[ "$i" -eq 5 ]]
do
echo $i
i=$[ $i + 1 ]
done
运行结果:
1
2
3
4
Shell 中的 break
用法与高级语言相同,都是跳出循环:
#!/bin/bash
for VAR in 1 2 3 4 5
do
if [ $VAR -eq 4 ]; then #不要忘了then
break
fi
echo $VAR
done
运行结果:
1
2
3
continue 用来跳过本次循环,进入下一次循环,例如:
#!/bin/bash
for VAR in 1 2 3 4 5
do
# 如果 VAR 等于 4,就跳过,直接进入下一次 VAR = 5 的循环
if [ $VAR -eq 4 ]
then
continue
fi
echo $VAR
done
运行结果:
1
2
3
5
每种编程语言中函数都占有重要地位,下面介绍 Shell 编程中比较重要的函数。
函数可以用一句话解释:带有输入输出的具有一定功能的黑盒子,相信有过编程经验的同学不会陌生。那么,我们先来看看 Shell 中函数定义的格式。
有 2 种常见格式:
#第一种
function fun_name()
{ }
#第二种
fun_name()
{ }
例如:
#!/bin/bash
hello()
{
echo "hello function"
}
function hello_world()
{
echo "hello_world function"
echo $1 $2 #打印第 1 2 个参数
return 5
}
如何调用上面的 2 个函数呢?
# 1.直接用函数名调用函数,如
hello
hello_world 1 2 #有参数记得跟上参数列表
# 2.使用 FUN=`函数名 [参数列表]` 来间接调用
FUN1=`hello`
FUN2=`hello_world 3 4`
echo $FUN1
echo $FUN2
运行结果
root@ubuntu:/home/linux_shell# bash function.sh
hello function
hello_world function
1 2
hello function
hello_world function 3 4
如何获取 hello_world
函数的返回值呢?还记得 $?
吗?
hello_world 1 2
# $? 可用于获取前一个函数的返回值,这里结果是 5
echo $?
运行结果:
root@ubuntu:/home/linux_shell# bash return.sh
hello_world function
1 2
5
shell中变量默认为全局变量,例如:
#!/bin/bash
VAR=123
#define function
example()
{
VAR=456
}
echo $VAR #改变前的VAR
example #调用函数
echo $VAR #改变后的VAR
#运行结果:
#123
#456
使用 local
来在函数中定义本地变量:
#!/bin/bash
VAR=123
#define function
example()
{
local VAR=456
echo $VAR
}
example #调用函数
echo $VAR #调用后的VAR
#运行结果:
#456
#123
俗话说,程序 3 分靠写、7 分靠调,下面我们就来看看如何调试 Shell 程序。
使用下面的命令来检查是否有语法错误:
sh -n script_name.sh
使用下面的命令来执行并调试 Shell 脚本:
sh -x script_name.sh
来看个实际的例子,我们来调试下面这个 test.sh
程序:
#!/bin/bash
for VAR in 1 2 3 4 5
do
if [ $VAR -eq 2 ]; then
continue
elif [ $VAR -eq 4 ]; then
continue
fi
echo $VAR
done
首先检查有无语法错误:
sh -n test.sh
没有输出,说明没有错误,开始实际调试:
sh -x test.sh
调试结果如下:
root@ubuntu:/home/linux_shell# bash -x debug.sh
+ for VAR in 1 2 3 4 5
+ '[' 1 -eq 2 ']'
+ '[' 1 -eq 4 ']'
+ echo 1
1
+ for VAR in 1 2 3 4 5
+ '[' 2 -eq 2 ']'
+ continue
+ for VAR in 1 2 3 4 5
+ '[' 3 -eq 2 ']'
+ '[' 3 -eq 4 ']'
+ echo 3
3
+ for VAR in 1 2 3 4 5
+ '[' 4 -eq 2 ']'
+ '[' 4 -eq 4 ']'
+ continue
+ for VAR in 1 2 3 4 5
+ '[' 5 -eq 2 ']'
+ '[' 5 -eq 4 ']'
+ echo 5
5
其中带有 +
表示的是 Shell
调试器的输出,不带 +
表示我们程序的输出。
初学者在 Shell 编程时容易犯的大多都是语法错误:
1. [ ]
内不能嵌套 ( )
,可以嵌套 [ ]
2. $[ val + 1 ]
是变量加 1 的常用方法
3. [ ]
在测试或者计算中里面的内容最好都加空格
4. 单引号和双引号差不多,单引号更加严格,双引号可以嵌套单引号
5. 一定要注意语句的格式,例如缩进、空格等.