赞
踩
Shell脚本是个十分便捷的东西,在日常工作中能在某种程度上提高我们得工作效率。Shell是一个命令解析器,简单来讲就是把各类命令丢到里面,从而可以使程序一次性执行,它不需要编译就可以直接执行。因此,使用Shell来进行一些重复性的工作,一些批量处理的工作等都是很高效的,为我们节省不少时间。
Linux的Shell种类众多,常见的有:Bourne Shell(/usr/bin/sH或/bin/sh)、Bourne Again Shell(/bin/bash)、C Shell(/usr/bin/csh)、K Shell(/usr/bin/ksh)、Shell for Root(/sbin/sh),等。
这里关注Bash,大多数Linux系统默认的就是Bash这个Shell,下面以它为例子进行学习总结。
1、Shell里并不像C语言一样使用变量时要提前声明,而是在使用的时候创建。
2、注意Shell里变量是区分大小写的。
3、默认以字符串方式存储,所以要想进行数值运算要做一些处理。
4、获取变量内容就在变量名前加$
。如:$var
。
以一段Shell为例:
#!/bin/bash #说明我们使用的是Bash
# TEST1
#值得注意的是,定义变量时 '='号左右两边不能有空格
var1=10 #定义变量var1
var2="Hi,Allen" #定义变量var2,字符串中有空格的情况,需要使用引号将字符串括起来
echo $var1 #输出变量var1的值
echo $var2 #输出变量var2的值
使用read
我们还可以用read来获取用户输入的值,将其赋给变量。通常按下回车read命令结束。
# TEST2
read var3 #读入用户输入
echo $var3
引号
以代码来理解:
# TEST3
my_name="Allen"
echo "This is $my_name" #把$expression放在双引号里,执行到时会把变量的值替换进来
echo 'This is $my_name' #把$expression放在单引号里,不会替换
echo "This is \$my_name" #在双引号里,$前加上 \ 转义字符来取消它的含义,同样不会替换
#有一种情况,按这样定义并不会输出"This is Allenhaha",因为他把my_namehaha认为是一个新变量,正确的做法是加上一对{}。
echo "This is $my_namehaha" #$expression为空
echo "This is ${my_name}haha" #正确的做法
输出如下:
This is Allen
This is $my_name
This is $my_name
This is
This is Allenhaha
参数变量
Shell脚本程序开始执行时,一些变量根据环境设置中的值进行初始化:
$HOME:当前用户的主目录;
$PATH:以冒号分隔的用来搜索命令的目录列表;
$0:Shell脚本的名字;
$#:传递给脚本的参数个数;
$$:Shell脚本的进程号,脚本程序通常会用它来生成一个唯一的临时文件。
如:
#TEST4
echo "脚本名: $0"
echo "参数个数: $#"
echo "home: $HOME"
echo "pid: $$"
输出:
脚本名: ./bash_test.sh
参数个数: 0
home: /home/tangbin
pid: 4341
数值运算
前面提到,变量的值默认是字符串存储,若想做一些运算,则可以这样做:
#TEST5
num1=20
num2=2
add=$(($num1+$num2))
sub=$(($num1-$num2))
mul=$(($num1*$num2))
div=$(($num1/$num2))
echo "$num1 + $num2 = $add"
echo "$num1 - $num2 = $sub"
echo "$num1 x $num2 = $mul"
echo "$num1 ÷ $num2 = $div"
输出:
20 + 2 = 22
20 - 2 = 18
20 x 2 = 40
20 ÷ 2 = 10
test
或[
命令
Shell的布尔判断命令[
或test
,当使用[
命令时,我们还使用符号]
来结尾。
例子:
#TEST6
if test -f my_file.sh
then
echo "my_file.sh exists."
fi
if [ -f tangbin.c ] #这里需注意 [ 和 ] 左右都要有空格;若里面有组件,每个组件都需要有空格来分隔;若里面有变量或者常量以" "括起来。
then
echo "tangbin.c exists."
else
echo "Can't find file"
fi
test的使用可以归为三类:
1.字符串比较;
2.算术比较;
3.文件相关的条件测试。
字符串比较 | 结果 |
---|---|
string1 = string2 | 如果两个字符串相同,结果就为真 |
string1 != string2 | 如果两个字符串不同,结果就为真 |
-n string | 如果字符串不为空,则结果为真 |
-z string | 如果字符串为一个空串(null),则结果为真 |
算术比较 | 结果 |
---|---|
expression1 -eq expression2 | 如果两个表达式相等,则结果为真 |
expression1 -ne expression2 | 如果两个表达式不等,则结果为真 |
expression1 -gt expression2 | 如果expression1大于expression2,则为真 |
expression1 -ge expression2 | 如果expression1大于等于expression2,则为真 |
expression1 -lt expression2 | 如果expression1小于expression2,则为真 |
expression1 -le expression2 | 如果expression1小于等于expression2,则为真 |
!expression | 表达式为假,则结果就为真;反之亦然 |
文件条件测试 | 结果 |
---|---|
-d file | 如果文件是一个目录,则为真 |
-f file | 如果文件是一个普通文件,则为真;也可以用来测试文件是否存在 |
-r file | 如果文件可读,则结果为真 |
-s file | 如果文件大小不为0,则结果为真 |
-w file | 如果文件可写,则结果为真 |
-x file | 如果文件可执行,则结果为真 |
类似于C语言,Shell里也有相应的控制结构:
if:
if condition
then
statements
else
statements
fi
上面已有例子。
elif:
if condition
then
statements
elif condition
then
statements
else
statements
fi
例子:
#TEST7
echo "Is it 9:00 PM? please answer yes or no."
read clock
if [ "$clock" = "yes" ] #记得此处的 [ = ]号左右空格;变量、常量都加上 " "
then
echo "Yes,it is."
elif [ "$clock" = "no" ] #同上
then
echo "No,it isn't."
else
echo "Sorry, $timeofday not recognized. Enter yes or no."
exit 1
fi
for:
for variable in values
do
statements
done
例子:
#TEST8
cd ~
mkdir shell_test
cd shell_test
for((i=0; i<10; i++)) #在~/shell_test下创建0~9个txt的文件
do
touch $i.txt
done
while:
while condition
do
statements
done
例子:
#TEST9
echo "Enter your name:"
read name
while [ "$name" != "Allen" ]
do
echo "Sorry, enter again."
read name
done
until:
与while类似,只是把条件反过来了。
until condition
do
statements
done
case:
case比较复杂,它具备匹配多个模式,然后执行多条相关语句的能力,这使得它非常适合于处理用户的输入。
case variable in
pattern [ | pattern] ...) statements;;
pattern [ | pattern] ...) statements;;
...
esac
例子:
#TEST10
echo "which books do you want? Enter: 1, 2, 3, 4"
read input
case "$input" in
1 ) echo "sanguoyanyi";;
2 ) echo "hongloumeng";;
3 ) echo "xiyouji";;
4 ) echo "shuihuzhuan";;
* ) echo "Sorry,can't find";;
esac
case执行,input内容会与下面的字符串匹配,一旦匹配成功,就会执行 )
后的语句 。 *
代表通配符,若没有匹配,则默认执行 *
后的默认动作。
&&和||操作符
这个C语言的规则是一样的。
statement1 && statement2 && statement3 && ...
statement1 || statement2 || statement3 || ...
Shell里也有函数,与C语言不同的是,不能在调用前进行声明。它是定义后才能调用。同样Shell函数里也能传入参数($*、$@、$#、$1、$2、$var1、$var2……等)
,当函数执行完毕后,这些参数会恢复为它们先前的值。也就是说,函数可以访问全局作用范围内的其它Shell变量。如果一个局部变量和一个全局变量的名字相同,前者就会覆盖后者,但仅限于函数的作用范围之内。
使用local
关键字可以在函数体里声明局部变量,local text="local_var"
function name()
{
statements
}
例子:
#TEST11
function Add()
{
echo "进行两数的相加运算:"
echo "input num1"
read num1
echo "input num2"
read num2
echo "相加结果为:"
return $(($num1+$num2)) #参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)
}
Add
echo "$?" #显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
Shell也是个程序,难免有出错的地方,像我们编写调试C程序可以借助gdb调试。Shell的调试可以以Bash的参数进行判断:
sh -n/-v/-x example.sh
-n:不要执行script,仅查询语法是否正确
-v:执行script之前,先将script的内容输出到屏幕
-x:将使用到的script内容显示到屏幕上(常用)
在此先简单总结到这里,Shell还有其他很多的知识点,比如一些常用命令。《鸟哥的Linux私房菜》都有比较详细的介绍,网上资料也很多,重点是想要熟练使用还得多自己编写程序才能加深理解。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。