首页 > 代码库 > shell脚本编程
shell脚本编程
shell脚本编程
1.基本概念
- shell中以
#
作为注释,使用方法和c中的//
完全相同 - shell中可以通过
;
在同一行执行两句命令,如ls ; pwd
- 脚本程序是顺序执行的,一句一句逐行解释执行
2.变量的使用
变量主要分为全局环境变量和私有变量(即局部环境变量),有关环境变量,详见 Linux环境变量详解
- 一个shell程序将继承其父shell的所有全局环境变量(即export的变量),并且可以对其重写而不影响父shell
- shell中的变量是无类型的。shell不支持浮点型只支持整型和字符串型,判断标准:变量中只包含数字的话是整型,包含了其他是字符就是字符串型
- 在shell脚本中可以随时定义变量,尤其要注意bash的语法中“=”两边不能有空格,变量值中间也不能有空格,有的话要用单引号围起来
test=123 #局部环境变量一般用小写
export TEST=123 #全局环境变量一般用大写
export MYNAME=‘XIAO BA WU‘ #变量值有空格,要用单引号围起来
export test #也可以这样把前面的局部变量导出到全局
此外,和c语言一样,变量必须先定义再使用。若使用了一个未定义的变量,倒是不会报错,相当于调用了一个值为空的变量
shell中,不能直接由变量名获取变量值,根本原因是shell中的字符串可以不加引号,所以系统无法判断它是字符串还是变量名,故通过
$
来引用变量名获取其值。而当变量名作为右值时,系统可以直接判定其为变量,无需添加$
value1=value2 //value1的值为字符串"value2"
value1=$value2 //value1的值为value2的值
- 此外$对变量名的判断是空格敏感的,当发生如下情况时,为了让bash能正确识别变量名,必须要使用{}将变量名包围,这是一个好习惯
name=123
name1=456
echo hah! hah! $name1 #打印name1的值
echo hah! hah! $name11 #打印name11的值(空值)
echo hah! hah! ${name}11 #打印name的值
- 当我们需要在一个字符串变量尾部,再续上几个字符时,可以:
name=‘aa bb cc d‘
name=$name‘d ee‘
$
在shell中是关键字,如果要在字符串中单纯显示$
符号,必须加\
。shell中,我们可以使用反引号` (就是键盘上~所处的键),来将命令的返回值赋给变量,如:
PATH=`pwd`
3.输入与输出
- echo可以直接打印字符串,一般情况不需要用单/双引号包围。但当字符串中出现单/双引号时,为了避免歧义,必须使用另外一种引号包围
echo abc123 #一般情况下直接打印
echo "let‘s go" #字符串里单引号,则用双引号包裹
echo ‘he says "shell is easy"‘ #字符串里双引号,则用单引号包裹
- 默认的,echo在打印字符串的后面,会自动加上换行符。若想取消这个特性,可以加参数
echo -n
- 我们可以重定向输出,即将指令的返回值导出到指定的某个文件,方法是使用
>
(覆盖写) 或>>
(追加写)
pwd > /home/root/path.txt #把pwd指令的返回值覆盖写入文件
echo $i >> /home/root/log.txt #把某个变量值追加写入文件
- 同理,我们还可以重定向输入,即将文件中的内容导入至命令(作为命令的参数),方法是使用
<
或<<
。说实话输入重定向用的很少,主要是命令可以直接以文件名作为参数,何必重定向呢。。。。
4.脚本的进入与退出
进入脚本
退出脚本
当脚本最后一句命令执行完,就会自动退出
- 在shell中的每个命令,在执行结束时都会返回给shell一个返回值,其值为0-255之间的整数值,一般0表示成功执行,正数表示发生了错误
- 我们可以使用
$?
来获取上条执行命令的返回值 - 脚本也可以由我们主动退出,在错误处理中经常使用,具体方法为
exit var
,var可以是我们指定的脚本退出时的返回值
5.数据操作
管道
管道的功能是:将一条命令的返回值,作为另一条命令的参数
- 其实不用管道,用中间变量也能实现该功能,但是太臃肿,还是管道好。下面的语句先执行command1,得到结果作为参数执行command2,得到结果作为参数执行command3
command1 | command2 | command3
数学运算
由于shell中的变量有可能是字符串或整形,所以运算起来很蛋疼
- 最原始的方法是使用expr命令,这种方法尤为蛋疼。用法如下,不仅要用到反引号来获取expr的输出,操作符前还要用到反斜杠,因为很多算数操作符在shell中是关键字(比如下面乘法操作符)
var1=1
var2=2
var=`expr $var1 \* $var2`
- bash中后来又引入了一种新方法,如下,shell会自动将&[]包围的部分视为数学运算,并且不会误解算数操作符
var1=1
var2=2
var=$[$var1 * $var2]
- 之前介绍的方法仅仅使用于整形运算,为了在shell中支持浮点运算,必须使用一个特殊的指令bc,即bash calculator。如下,通过管道将参数传给bc,用scale=4来指定结果要保留几位小数
var1=1
var2=3
var=`echo "scale=4; $var1 / $var2" | bc`
6.判断与循环结构
if语句
- shell中的if语句结构如下,它通过判断command1的返回值,若0(即命令成功执行)则执行command2、command3;若1则不执行
if commandA
then
command1
command2
fi
#另一种风格的写法
if commandA; then
command1
command2
fi
- 当然shell中也有else,还有elseif,用法分别如下:
if commandA
then
command1
else
command2
fi
if commandA
then
command1
elif commanB
then
command2
elif commandC
then
command3
fi
- 当需要多次判断时,也可用switch case来替代if else
case $USR in
root)
echo root
echo oh!;;
jack)
echo jack;;
peter | ben) #满足jack或ben
echo hah! hah!;;
*) #星号代表默认情况
echo error;;
esac
test语句
- test命令是if语句的好伴侣,常用来判断条件是否满足,满足返回0,不满足返回1;test可以用来比较:数值、字符串、文件/路径。常见用法为:
if test condition
then
commands
fi
#bash支持的另一种格式,本质也是调用了test,千万要注意在condition和方括号之间加空格
if [ condition ]
then
commands
fi
- 当test用于数值比较时,基本格式为
var1 参数 var2
,如下,具体参数有很多,可以上网查
if [ $var1 -eq $var2 ] #判断var1和var2变量值是否相等
if [ $var1 -gt 2 ] #判断var1的变量值是否大于2
- 当test用于字符串比较时,基本格式也为
var1 符号 var2
,此外还可以使用[[ ]]
来使用正则匹配
if [ $string1 = $string2 ] #判断变量string1和string2值是否相等
if [ $USR = !root ] #判断变量USR值是否不等于root
if [[ $USR == r* ]] #判断变量USR值是否以字母r开头
- 当test用于判断文件和目录的状态时,基本格式为
参数 filepath
如下,具体参数有很多,可以上网查
if [ -d $MYPATH ] #判断位于$MYPATH的文件是否存在,并且是个目录
if [ -e $MYPATH ] #判断位于$MYPATH的文件是否存在
if [ -r $MYPATH ] #判断位于$MYPATH的文件是否可读
if [ -x $MYPATH ] #判断位于$MYPATH的文件是否可执行
- test 还可以判断一个变量是否有值
if [ -z "$USR" ] #判断变量USR长度是否为零
if [ -n "$USR" ] #判断变量USR长度是否非零
- 对于复合判断语句,shell中使用
&&
和||
来表示,尤其需要注意的是,shell中以命令返回0为真,1位假,故&&
和||
操作以逻辑真假为准,不再以数值上的0和1为准
if [ condition1 ] && [ condition2 ]
if [ condition1 ] || [ condition2 ]
- 此外&&还能用来作为简易版本的if语句,左边的命令返回真(即返回0),右边的命令才被执行
[ $? -ne 0 ] && mk_error "build rootfs Failed" && return 1
for语句
- shell中for语句的基本用法是,每次循环,变量就套用列表中的元素值,循环至列表结束为止
#for语句假定列表元素之间以空格分割,若元素内部包含空格,则用双引号包围即可
for var in shanghai beijing "new york" guangzhou
do
commands
done
#for语句也可以将变量的内容作为列表值
list=‘shanghai beijing guangzhou‘
for var in $list
do
commands
done
#列表值的来源也可以是指令的输出,for将以空格来分割指令的输出,当输出结束时循环也结束
for var in `cat $file` #此处从一个文件中读取内容,以此作为列表值
do
commands
done
- 现在来系统的讨论一下,for语句会将哪些字符作为列表元素的分割符?默认为空格、换行、制表符。我们可以通过变量IFS来指定分隔符,这是极为便利的一种机制
OLDIFS=$IFS #先备份原本的IFS值
IFS=$‘\n:;‘ #指定分隔符为换行符、冒号、分号
#这里可以进行各种操作了
IFS=$OLDIFS #还原IFS值
- for语句还有一种强大的用法,即用通配符获取文件/目录
#这里将会遍历所有满足条件的目录,并将其作为列表值,每次循环赋给变量file
for file in /home/root/.b* /home/root/test
do
if [ -d $file ]
.....
shell脚本编程
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。