shell脚本相关总结2

一、测试

1.测试
在程序运行中经常需要根据实际情况来运行特定的命令或代码块。
比如判断某个文件或目录是否存在?如果不存在,则需要创建。

[root@localhost ~]# ls /var/log/messages
/var/log/messages
[root@localhost ~]# echo $?
0
[root@localhost ~]# ls /var/log/messages044
ls: /var/log/messages044: No such file or directory
[root@localhost ~]# echo $?
2

2.测试的结构主要有两种
(1)使用test命令

test expression

其中expression是一个表达式,可以是算术比较、字符串比较、文本和文件属性比较等。
(2)使用[]

[ expression ]

注意括号和表达式expression之间都有空格。推荐使用第二种方式。
例如:判断文件是否存在

[root@localhost ~]# test -e /var/log/messages
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ -e /var/log/messages ]
[root@localhost ~]# echo $?
0

3.文件测试参数

参数作用
-e文件或目录是否存在
-f文件存在且为普通文件
-d目录是否存在
-w file当文件存在且为可写文件时返回真,否则为假
-r file当文件存在且为可读文件时返回真,否则为假
-x file当文件存在且为可执行文件时返回真,否则为假
-l file当文件存在且为链接文件时返回真,否则为假
-p file当文件存在且为管道文件时返回真,否则为假
-s file当文件存在且大小不为0时返回真,否则为假
-S file当文件存在且为socket文件时返回真,否则为假
-g file当文件存在且设置了SGID时返回真,否则为假
-u file当文件存在且设置了SUID时返回真,否则为假
-k file当文件存在且设置了sticky属性时返回真,否则为假
-G file当文件存在且属于有效的用户组时返回真,否则为假
-O file当文件存在且属于有效的用户时返回真,否则为假
file1 -nt file2当file1比file2新时,返回为真,否则为假
file1 -ot file2当file1比file2旧时,返回为真,否则为假

示例

[root@localhost ~]# vim rwx.sh
#!/bin/bash
read -p "what file do you want to test?:" filename
if [ ! -e "$filename" ];then
    echo "the file does not exist."
    exit 1
fi
if [ -r "$filename" ];then
    echo "$filename is readable."
fi
if [ -w "$filename" ];then
    echo "$filename is writeable."
fi
if [ -x "$filename" ];then
    echo "$filename is executable."
fi
[root@localhost ~]# bash rwx.sh
what file do you want to test?:/etc
/etc is readable.
/etc is writeable.
/etc is executable.

二、条件判断

1.if判断结构
最简单的判断语句,可以针对测试结果做相应处理;如果测试为真则运行相关代码,其语法结构如下:

if expression;then
command
fi

如果expression测试返回真,则执行command。如果执行不止一条命令,则不同命令之间用换行符隔开,如下所示:

if expression;then
         command1
         command2
         ...
fi

2.常用参数

参数作用
-eq检测两个数是否相等,相等返回true,否则返回false
-ne检测两个数是否不相等,不相等返回true,否则返回true
-gt检测左边的数是否大于右边的,如果是,则返回true,否则返回false
-lt检测左边的数是否小于右边的,如果是,则返回true,否则返回false
-ge检测左边的数是否大于等于右边的,如果是,则返回true,否则返回false
-le检测左边的数是否小于等于右边的,如果是,则返回 true,否则返回true

示例
写一个脚本,判断用户得分情况。
如果小于30分,那么输出“太低了!”
如果大于等于30分且小于60分,则输出"加油!"
如果大于等于60分且小于85分,则输出“不错!”
如果大于等于85分且小于100分,则输出“优秀!”
如果等于100分,则输出“人才!”

[root@localhost ~]# vim score.sh
#!/bin/bash
echo -n "please input a score:"
read SCORE
if [ "$SCORE" -lt 30 ];then
    echo "太低了!"
fi
if [ "$SCORE" -ge 30 -a "$SCORE" -lt 60 ];then
    echo "加油!"
fi
if [ "$SCORE" -ge 60 -a "$SCORE" -lt 85 ];then
    echo "不错!"
fi
if [ "$SCORE" -ge 85 -a "$SCORE" -lt 100 ];then
    echo "优秀!"
fi
if [ "$SCORE" -eq 100 ];then
    echo "人才!"
fi

2.if/else判断结构
如果if后的判断成立,则执行then后面的内容;否则执行else后面的内容。
语法结构如下:

if expression;then
	command1
else
	command2
fi

示例

[root@localhost ~]# vim check.sh
#!/bin/bash
read -p "请输入你要查询的目录或文件名:" FILE
if [ -e $FILE ];then
    echo "$FILE 有!"
else
    echo "$FILE 没有!"
fi
[root@localhost ~]# bash check.sh
请输入你要查询的目录或文件名:/etc
/etc 有!
[root@localhost ~]# bash check.sh
请输入你要查询的目录或文件名:cda
cda 没有!

3.if/elif/else判断结构
可以代替if嵌套。
语法结构如下:

if expression1;then
	command1
elif expression2;then
	command2
elif expression3;then
	command3
...
fi

示例
写一个脚本,查询用户是否存在,如果存在,则输出“有此用户,它的UID为:”,如果没有则输出“没有此用户。”
(1)如果使用if判断语句,则可以这样编写:

[root@localhost ~]# vim testusr.sh
#!/bin/bash
read -p "请输入想要查询的用户名:" USER
id $USER &> /dev/null
if [ $? -ne 0 ]
then
         useradd $USER
         echo "没有此用户,并已经为您添加此用户。添加后此用户UID为 `id -u $USER`"
else
         echo "此用户已经存在,UID为`id -u $USER`"
fi
[root@localhost ~]# bash testusr.sh
请输入想要查询的用户名:root
此用户已经存在,UID为0
[root@localhost ~]# bash testusr.sh
请输入想要查询的用户名:nihao
没有此用户,并已经为您添加此用户。添加后此用户UID为 2021

输出重定向

符号意义
>覆盖重定向
>>追加重定向
2>错误重定向
2>>错误追加重定向
&>同时重定向,不管正确与否
/dev/null数据黑洞

(2)上面的例子一般不会直接添加用户,所以可以利用if/elif/else语法修改一下。

#!/bin/bash
read -p "请输入想要查询的用户名:" USER
id $USER &> /dev/null
if [ $? -ne 0 ]
then
        read -p "没有此用户,请问是否创建此用户?Y/N" YN
                if [ $YN == Y ];then
                        useradd $USER
                        echo "用户添加成功,用户ID为`id -u $USER`"
                elif [ $YN == N ];then
                        echo "好的,不进行任何操作,欢迎下次再来!"
                else
                        echo "您的输入有误!"
                fi
else
        echo "此用户已经存在,UID为`id -u $USER`"
fi
[root@localhost ~]# bash testusr.sh
请输入想要查询的用户名:nihao
没有此用户,请问是否创建此用户?Y/NY
用户添加成功,用户ID为2021
[root@localhost ~]# bash testusr.sh
请输入想要查询的用户名:ni
没有此用户,请问是否创建此用户?Y/NN
好的,不进行任何操作,欢迎下次再来!

颜色方面的参数

参数意义
\e[1;m设置高亮加粗
\e[4;m添加下划线
\e[5;m闪烁
31m红色
32m绿色
33m黄色
34m蓝色
35m紫色
36m青色
37m白色
[root@localhost ~]# echo -e "\e[1;31m红色\e[0m"
红色
[root@localhost ~]# echo -e "\e[4;31m红色\e[0m"
红色
[root@localhost ~]# echo -e "\e[5;31m红色\e[0m"
红色

示例
写一个脚本,要求:用户输入七种颜色之一,根据用户输入的颜色打印出相应的颜色。

[root@localhost ~]# vim yanse.sh
#!/bin/bash
echo "您能输入的颜色有:红色、绿色、黄色、蓝色、紫色、青色、白色"
read -p "请输入你要选取的颜色:" COLOR
if [ $COLOR == "红色" ];then
      echo -e "\e[1;31m红色\e[0m"
elif [ $COLOR == "绿色" ];then
      echo -e "\e[1;32m绿色\e[0m"
elif [ $COLOR == "黄色" ];then
      echo -e "\e[1;33m黄色\e[0m"
elif [ $COLOR == "蓝色" ];then
      echo -e "\e[1;34m蓝色\e[0m"
elif [ $COLOR == "紫色" ];then
      echo -e "\e[1;35m紫色\e[0m"
elif [ $COLOR == "青色" ];then
      echo -e "\e[1;36m青色\e[0m"
elif [ $COLOR == "白色" ];then
      echo -e "\e[1;37m白色\e[0m"
else
      echo "您的输入有误!"
fi
[root@localhost ~]# bash yanse.sh
您能输入的颜色有:红色、绿色、黄色、蓝色、紫色、青色、白色
请输入你要选取的颜色:红色
红色
[root@localhost ~]# bash yanse.sh
您能输入的颜色有:红色、绿色、黄色、蓝色、紫色、青色、白色
请输入你要选取的颜色:蓝色
蓝色
[root@localhost ~]# bash yanse.sh
您能输入的颜色有:红色、绿色、黄色、蓝色、紫色、青色、白色
请输入你要选取的颜色:白色
白色
[root@localhost ~]# bash yanse.sh
您能输入的颜色有:红色、绿色、黄色、蓝色、紫色、青色、白色
请输入你要选取的颜色:你
您的输入有误!

4.case判断结构
用于多种可能情况下的分支选择。
语法结构如下:

case var in
var1)
	command1;;
var2)
	command2;;
var3)
	command3;;
...
*)
	command6;;
esac

其原理为从上而下依次比较var和var1、var2、var3的值是否相等,如果匹配则执行其后面的命令,都不匹配则执行最后的命令。
注意case判断结构中的var1、var2、var3等这些值只能是常量或正则表达式。
示例1
检测当前操作系统

[root@localhost ~]# vim os.sh
#!/bin/bash
OS=`uname -s`
case "$OS" in
FreeBSD)
        echo "this is FreeBSD";;
SunOS)
        echo "this is Solaris";;
Darwin)
        echo "this is Mac OSX";;
Linux)
        echo "this is Linux";;
*)
        echo "Failed to identify this OS";;
esac
[root@localhost ~]# bash os.sh
this is Linux

示例2
上面颜色的例子用case改写

[root@localhost ~]# vim yanse.sh
#!/bin/bash
echo "您能输入的颜色有:红色、绿色、黄色、蓝色、紫色、青色、白色"
read -p "请输入你要选取的颜色:" COLOR
case "$COLOR" in
红色)
        echo -e "\e[1;31m红色\e[0m";;
绿色)
        echo -e "\e[1;32m绿色\e[0m";;
黄色)
        echo -e "\e[1;33m黄色\e[0m";;
蓝色)
        echo -e "\e[1;34m蓝色\e[0m";;
紫色)
        echo -e "\e[1;35m紫色\e[0m";;
青色)
        echo -e "\e[1;36m青色\e[0m";;
白色)
        echo -e "\e[1;37m白色\e[0m";;
*)
        echo "您的输入有误!";;
esac
[root@localhost ~]# bash yanse.sh
您能输入的颜色有:红色、绿色、黄色、蓝色、紫色、青色、白色
请输入你要选取的颜色:ni
您的输入有误!
[root@localhost ~]# bash yanse.sh
您能输入的颜色有:红色、绿色、黄色、蓝色、紫色、青色、白色
请输入你要选取的颜色:黄色
黄色

三、function功能

函数可以在shell script当中做出一个类似自动执行指令的东西,最大的功能是可以简化程序码。如果输出的内容都一样,那么就可以使用function来简化。
语法结构如下:

function fname () {
	command
}

fname是需要自动执行的指令名称,而程序段就是要他执行的内容。
注意:因为shell script的执行方式是由上而下,由左而右,因此在shell script中function的设置一定要在程序的最前面,这样才能够在执行时被找到。
示例
使用function功能简化代码。

[root@localhost ~]# vim zhuangbei.sh
#!/bin/bash
read -p "请输入你要查询的装备类别:" INPUT
read -p "请输入装备的分数:" SCORE
function fenshu () {
         if [ $SCORE -le 30 ];then
                echo "品相极渣!"
         elif [ $SCORE -gt 30 -a $SCORE -le 65 ];then
                echo "渣渣!"
         elif [ $SCORE -gt 65 -a $SCORE -le 95 ];then
                echo "嗯,这才像个样!"
         elif [ $SCORE -gt 95 ];then
                echo "谁与争锋!"
         else
                echo "输入有误!"
         fi
}
function chongzhu () {
         read -p "请问是否选择重铸!Y/N" YN
         if [ $YN == Y ];then
                   read -p "好的,用户选择重铸"
         elif [ $YN == N ];then
                   echo "用户不重铸,886!"
         else
                   echo "输入有误!"
         fi
}
case $INPUT in
toukui)
       fenshu;chongzhu;;
jianbang)
       fenshu;chongzhu;;
xiongjia)
       fenshu;chongzhu;;
*)
       echo "没有这个装备";;
esac
[root@localhost ~]# bash zhuangbei.sh
请输入你要查询的装备类别:xiongjia
请输入装备的分数:90
嗯,这才像个样!
请问是否选择重铸!Y/NN
用户不重铸,886!
四、while循环、until do done(不定循环)

shell中的循环主要有for、while、until、select几种。
1.while循环

while [ condition ]  #状态的判读
do  #循环的开始
	command
done  #循环的结束

当condition条件成立时进行循环,直到condition的条件不成立才停止。
2.until循环

until [ condition ]
do
	command
done

与while相反,当condition条件成立时,就终止循环,否则就持续进行循环的程序段。
示例1

[root@localhost ~]# vim while.sh
#!/bin/bash
while [ "${yn}" != "yes" ]
do
      read -p "请输入'yes'退出: " yn
done
echo "退出成功!"
[root@localhost ~]# bash while.sh
请输入'yes'退出: no
请输入'yes'退出: no
请输入'yes'退出: yes
退出成功!

示例2

[root@localhost ~]# vim until.sh
#!/bin/bash
until [ "${yn}" == "yes" ]
do
       read -p "请输入'yes'退出: " yn
done
echo "退出成功!"
[root@localhost ~]# bash until.sh
请输入'yes'退出: no
请输入'yes'退出: yes
退出成功!

3.关于变量取值

[root@localhost ~]# vim 1.sh
#!/bin/bash
i=0
let i=$i+1
echo $i
[root@localhost ~]# bash 1.sh
1

关于下面那个i的值已经是新的变量了,格式还可以这么写。

let i=$i+1   -----  let i+=1     ------    let i++
三者等价

示例1
求1+2+3+4…+100的值是多少?

[root@localhost ~]# vim qiuhe.sh
#/bin/bash
s=0 i=0
while [ $i != 100 ]
do
       let i+=1
       let s=$s+$i
done
echo "1+2+3...+100等于$s"
[root@localhost ~]# bash qiuhe.sh
1+2+3...+100等于5050

示例2
让用户输入密码,如果输入错误超过5次,就退出。

[root@localhost ~]# vim denglu.sh
#!/bin/bash
i=1
while [ "$MIMA" != "123.com" -a $i -le 5 ]
do
        let i+=1
        read -p "请输入密码:" MIMA
done
if [ $i -le 5 ];then
        echo "登录成功!"
else
        echo "已经超过5次,退出!"
fi
[root@localhost ~]# bash denglu.sh
请输入密码:123.com
登录成功!
[root@localhost ~]# bash denglu.sh
请输入密码:1
请输入密码:1
请输入密码:1
请输入密码:1
请输入密码:1
已经超过5次,退出!
五、for循环

最常见的循环结构。for循环是一种运行前测试语句,也就是在运行任何循环体之前先要判断循环条件是否成立,只有在条件成立的情况下才会运行循环体,否则将退出循环。每完成一次循环后,在进行下一次循环之前都会再次进行测试。
带列表的for循环用于执行一定次数的循环(循环次数等于列表元素个数),其语法结构如下:

for var in con1 con2 con3
do
         command
done

第一次循环时,$var的内容为con1;
第二次循环时,$var的内容为con2;
第三次循环时,$var的内容为con3;

示例1

[root@localhost ~]# vim fruit.sh
#!/bin/bash
for FRUIT in apple orange banana pear
do
       echo "$FRUIT is john's favorite!"
done
       echo "no more fruits"
[root@localhost ~]# bash fruit.sh
apple is john's favorite!
orange is john's favorite!
banana is john's favorite!
pear is john's favorite!
no more fruits

示例2
为了便于修改,可以先定义变量,然后再用变量替代列表。

#!/bin/bash
fruits="apple orange banana pear"
for FRUIT in ${fruits}
do
       echo "$FRUIT is john's favorite!"
done
       echo "no more fruits"
[root@localhost ~]# bash fruit.sh
apple is john's favorite!
orange is john's favorite!
banana is john's favorite!
pear is john's favorite!
no more fruits

示例3
当然变量也可以是数字

[root@localhost ~]# vim list.sh
#!/bin/bash
for var in {1..10}
do
        echo "loop $var times"
done
[root@localhost ~]# bash list.sh
loop 1 times
loop 2 times
loop 3 times
loop 4 times
loop 5 times
loop 6 times
loop 7 times
loop 8 times
loop 9 times
loop 10 times

示例4
也可以利用这个去求和

[root@localhost ~]# vim qiuhe1.sh
#!/bin/bash
sum=0
for i in `seq 1 100`
do
         let sum+=${i}
done
echo "total:${sum}"
[root@localhost ~]# bash qiuhe1.sh
total:5050

示例5
还可以使用“步长”计算1到100的奇数和

[root@localhost ~]# vim jishu.sh
#!/bin/bash
sum=0
for VAR in `seq 1 2 100`
#for VAR in $(seq 1 2 100)
do
       let "sum+=${VAR}"
done
echo "Total: ${sum}"
[root@localhost ~]# bash jishu.sh
Total: 2500
六、类C的for循环

格式如下:

for ((expression1;expression2;expression3))
do
      command
done

相关解释

expression1:为初始化语句,一般用作变量定义和初始化;

expression2:为判断表达式,用于测试表达式返回值并以此控制循环,返回值为真则循环继续,返回值为假则退出循环;

expression3:用于变量值修改,从而影响expression2的返回值,并以此影响循环行为;

示例1

[root@localhost ~]# vim c.sh
#!/bin/bash
for ((i=1;i<=10;i++))
do
      echo "$i"
done
[root@localhost ~]# bash c.sh
1
2
3
4
5
6
7
8
9
10

示例2
倒数5秒

[root@localhost ~]# vim daoshu.sh
#!/bin/bash
echo "准备倒数5秒:"
for i in `seq 5 -1 1`
do
      echo -en "$i";sleep 1
done
echo -e "开始"
[root@localhost ~]# bash daoshu.sh
准备倒数5秒:
54321开始

示例3
批量添加用户

[root@localhost ~]# cat >> user.txt << EOF
> zhangsan
> lisi
> wangwu
> zhaoliu
> EOF
[root@localhost ~]# cat user.txt
zhangsan
lisi
wangwu
zhaoliu
[root@localhost ~]# vim user.sh
#!/bin/bash
for i in $(cat /root/user.txt)
do
         useradd $i
         echo "123.com" | passwd --stdin $i
done
[root@localhost ~]# bash user.sh
更改用户 zhangsan 的密码 。
passwd:所有的身份验证令牌已经成功更新。
更改用户 lisi 的密码 。
passwd:所有的身份验证令牌已经成功更新。
更改用户 wangwu 的密码 。
passwd:所有的身份验证令牌已经成功更新。
更改用户 zhaoliu 的密码 。
passwd:所有的身份验证令牌已经成功更新。
[root@localhost ~]# tail -4 /etc/passwd
zhangsan:x:2021:2021::/home/zhangsan:/bin/bash
lisi:x:2022:2022::/home/lisi:/bin/bash
wangwu:x:2023:2023::/home/wangwu:/bin/bash
zhaoliu:x:2024:2024::/home/zhaoliu:/bin/bash

总结

(1)while循环的特长是执行守护进程以及希望循环不退出持续执行的情况,用于频率小于一分钟循环处理。
其他的while循环几乎都可以被for循环替代。

(2)case语句可以替换if语句,一般在系统启动脚本传入少量固定规则字符串,用case语句。
其他普通判断多用if语句。

(3)if和for语句最常用,其次是while(守护进程),case(服务启动脚本)

各个语句的应用场景:

条件表达式,简单的判断(文件是否存在,字符串是否为空等)。
if取值判断,不同值数量较少的情况。

for循环正常的循环处理,最常用。

while循环守护进程、无限循环(sleep)。

case服务启动脚本,菜单。
函数逻辑清晰,减少重复语句。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值