Shell脚本进阶

Shell脚本进阶

一. bash条件判断

1. 条件测试类型
  • 整数测试,大于,小于等于,不等于,大于等于,小于等于
  • 字符测试,两边类似
  • 文件测试,文件是否存在,文件类型,文件大小,有无数据
2. 条件测试的表达式
[ expression ]
[[ expression ]]
test expression
3. 整数测试(双目,两个对象)
-eq     //测试两个整数是否相等 equal
-ne     //测试两个整数是否不等 not equal
-gt     //测试一个数是否大于另一个数 greater than
-lt     //测试一个数是否小于另一个数 less than
-ge     //大于或等于 Greater than or equal
-le     //小于或等于 Less than or equal

是否相等:
[root@SYL4 ~]# [ 2 -eq 2 ] 22 是否相等
[root@SYL4 ~]# echo $?
0  条件成立

是否不等:
[root@SYL4 ~]# [ 2 -ne 2 ] 22是否不相等
[root@SYL4 ~]# echo $?
1  条件不成立
[root@SYL4 ~]# 

[root@SYL4 ~]# [ 2 -lt 3 ] 2小于3
[root@SYL4 ~]# echo $?
0

小于或等于
[root@SYL4 ~]# [ 2 -le 3 ] 2 <= 3
[root@SYL4 ~]# echo $?
0
[root@SYL4 ~]# 
4. 字符测试
==      //等值比较,检查==两边的内容是否一致,==两边都要有空格
!=      //检查两边内容是否不一致,不一致为真,一致为假
=~      //左侧字符串是否能够被右侧的PATTERN所匹配到。此表达式应用于双中括号[[]]中
-z "string"     //测试指定字符串是否为空,空则为真,不空则为假
-n "string"     //测试指定字符串是否不空,不空则为真,空则为假



[root@SYL4 ~]# [ 'abc' == 'abcd' ]
[root@SYL4 ~]# echo $?
1
[root@SYL4 ~]# 
  
[root@SYL4 ~]# [ 'abc' != 'abcd' ]
[root@SYL4 ~]# echo $?
0
[root@SYL4 ~]# 

点代表通配符,字符,左侧字符串是否能够被右侧的PATTERN所匹配到   
[root@SYL4 ~]# [[ "abc" =~ "..." ]]
[root@SYL4 ~]# echo $?
1
[root@SYL4 ~]# [[ "abc" =~ ... ]]
[root@SYL4 ~]# echo $?
0
[root@SYL4 ~]# 
[root@SYL4 ~]# [[ "abc" =~ .. ]]
[root@SYL4 ~]# echo $?
0
[root@SYL4 ~]# [[ "abc" =~ .... ]]
[root@SYL4 ~]# echo $?
1
[root@SYL4 ~]# 
[root@SYL4 ~]# echo 'abc'|grep ab
abc
[root@SYL4 ~]# echo 'abc'|grep ..
abc
[root@SYL4 ~]# echo 'abc'|grep ....
[root@SYL4 ~]# 

    
测试指定字符串是否为空,空则为真,不空则为假 
[root@SYL4 ~]# [ -z '' ]
[root@SYL4 ~]# echo $?
0
[root@SYL4 ~]# [ -z ' ' ]
[root@SYL4 ~]# echo $?
1
[root@SYL4 ~]# [ -z 'null' ]
[root@SYL4 ~]# echo $?
1
    
    
测试指定字符串是否不空,不空则为真,空则为假  
[root@SYL4 ~]# [ -n '' ]
[root@SYL4 ~]# echo $?
1
[root@SYL4 ~]# [ -n ' ' ]
[root@SYL4 ~]# echo $?
0
[root@SYL4 ~]# [ -n 'aa' ]
[root@SYL4 ~]# echo $?
0
[root@SYL4 ~]#  
5. 文件测试
//存在性测试:
    -e      //测试文件是否存在

[root@SYL4 ~]# [ -e abc ]
[root@SYL4 ~]# echo $?
0


//存在性及类别测试:
    -b      //测试文件是否为块设备文件
[root@SYL4 ~]# ll /dev/sr0 
brw-rw----. 1 root cdrom 11, 0 Jul 14 16:47 /dev/sr0
[root@SYL4 ~]# [ -b /dev/sr0 ]
[root@SYL4 ~]# echo $?
0
[root@SYL4 ~]# [ -b /dev/sr1 ]
[root@SYL4 ~]# echo $?
1
[root@SYL4 ~]# 



    -c      //测试文件是否为字符设备文件
[root@SYL4 ~]# [ -c /dev/sr0 ]
[root@SYL4 ~]# echo $?
1
[root@SYL4 ~]# 



    -f      //测试文件是否为普通文件
[root@SYL4 ~]# ll
total 8
-rw-r--r--. 1 root root    0 Jul 14 17:27 abc
-rw-------. 1 root root 1093 Apr 11 09:59 anaconda-ks.cfg
drwxr-xr-x. 2 root root   78 Jul 14 17:09 scripts
-rwxr-xr-x. 1 root root  140 Jul 14 17:23 test.sh
[root@SYL4 ~]# [ -f abc ]
[root@SYL4 ~]# echo $?
0


    -d      //测试指定路径是否为目录
[root@SYL4 ~]# ls
abc  anaconda-ks.cfg  scripts  test  test.sh
[root@SYL4 ~]# [ -d test ]
[root@SYL4 ~]# echo $?
0
[root@SYL4 ~]# 


    -h      //测试文件是否为符号链接文件
    -L      //测试文件是否为符号链接文件
    -p      //测试文件是否为命名管道文件
    -S      //测试文件是否为套接字文件


//文件权限测试:
    -r      //测试当前用户对指定文件是否有读权限
    -w      //测试当前用户对指定文件是否有写权限
    -x      //测试当前用户对指定文件是否有执行权限
[root@SYL4 ~]# id tom
uid=1001(tom) gid=1001(tom) groups=1001(tom)
[root@SYL4 ~]# su - tom
Last login: Tue Jul 12 19:21:18 CST 2022 on pts/2
[tom@SYL4 ~]$ cd /tmp/
[tom@SYL4 tmp]$ ll abc 
-rw-r--r--. 1 root root 0 Jul 14 17:35 abc
[tom@SYL4 tmp]$ [ -r abc ]
[tom@SYL4 tmp]$ echo $?
0
[tom@SYL4 tmp]$ [ -w abc ]
[tom@SYL4 tmp]$ echo $?
1
[tom@SYL4 tmp]$ [ -x abc ]
[tom@SYL4 tmp]$ echo $?
1
[tom@SYL4 tmp]$ 


//文件特殊权限测试:
    -g      //测试文件是否有sgid权限
    -u      //测试文件是否有suid权限
    -k      //测试文件是否有sticky权限
[root@SYL4 ~]# ll /
drwxrwxrwt.  13 root root  273 Jul 14 17:38 tmp

[tom@SYL4 ~]$ cd /tmp/
[tom@SYL4 tmp]$ [ -k /tmp/ ]
[tom@SYL4 tmp]$ echo $?
0
[tom@SYL4 tmp]$ 


//文件大小测试:
    -s      //测试文件是否非空
不空为真
[root@SYL4 ~]# echo 'aaa' > abc
[root@SYL4 ~]# [ -s abc ]
[root@SYL4 ~]# echo $?
0
[root@SYL4 ~]# > abc
[root@SYL4 ~]# [ -s abc ]
[root@SYL4 ~]# echo $?
1
[root@SYL4 ~]# 



//文件是否打开测试:
    -t fd   //fd表示的文件描述符是否已经打开且与某终端相关
[tom@SYL4 ~]$ vim 123 打开,不关闭
[root@SYL4 ~]# ps -ef|grep vim
tom       284996  170726  0 17:58 pts/2    00:00:00 vim 123
root      287908  259191  0 17:59 pts/6    00:00:00 grep --color=auto vim
[root@SYL4 ~]# cd /proc/284996/fd
[root@SYL4 fd]# ll
total 0
lrwx------. 1 tom tom 64 Jul 14 17:59 0 -> /dev/pts/2
lrwx------. 1 tom tom 64 Jul 14 17:59 1 -> /dev/pts/2
lrwx------. 1 tom tom 64 Jul 14 17:59 2 -> /dev/pts/2
lr-x------. 1 tom tom 64 Jul 14 17:59 3 -> /var/lib/sss/mc/passwd
lrwx------. 1 tom tom 64 Jul 14 17:59 4 -> /home/tom/.123.swp
[root@SYL4 fd]# ll
total 0
[root@SYL4 fd]# 


//双目测试:
    file1 -ef file2     //测试file1与file2是否指向同一个设备上的相同inode,说白点就是两者是不是同一个文件
    file1 -nt file2     //测试file1是否比file2新
    file1 -ot file2     //测试file1是否比file2旧
inode号,文件存在磁盘的哪个磁盘块位置的inode
[root@SYL4 ~]# ln abc 123
[root@SYL4 ~]# ll -i
total 12
33575944 -rw-r--r--. 2 root root    0 Jul 14 17:44 123
33580188 -rw-r--r--. 1 root root    5 Jul 14 17:58 666
33575944 -rw-r--r--. 2 root root    0 Jul 14 17:44 abc
33575045 -rw-------. 1 root root 1093 Apr 11 09:59 anaconda-ks.cfg
17428614 drwxr-xr-x. 2 root root   86 Jul 14 17:56 httpd
17246521 drwxr-xr-x. 2 root root   78 Jul 14 17:09 scripts
33575983 -rwxr-xr-x. 1 root root  140 Jul 14 17:23 test.sh
[root@SYL4 ~]# 
[root@SYL4 ~]# [ abc -ef 123 ]
[root@SYL4 ~]# echo $?
0
[root@SYL4 ~]# [ abc -ef 123d ]
[root@SYL4 ~]# echo $?
1
[root@SYL4 ~]# 

[root@SYL4 ~]# [ abc -ot anaconda-ks.cfg ]
[root@SYL4 ~]# echo $?
1
[root@SYL4 ~]# ll
total 8
-rw-r--r--. 1 root root    0 Jul 14 17:44 abc
-rw-------. 1 root root 1093 Apr 11 09:59 anaconda-ks.cfg
abc比anaconda-ks.cfg 旧,



//无分类:
    -N      //测试文件自从上一次被读取之后是否被修改过
    -O      //测试文件是否存在并且被当前用户拥有
    -G      //测试文件是否存在并且默认组是否为当前用户组

测试文件自从上一次被读取之后是否被修改过
[root@SYL4 ~]# cat abc
[root@SYL4 ~]# [ -N abc ]
[root@SYL4 ~]# echo $?
1
[root@SYL4 ~]# echo '122' >  abc
[root@SYL4 ~]# [ -N abc ]
[root@SYL4 ~]# echo $?
0
[root@SYL4 ~]# 

测试文件是否存在并且被当前用户拥有
[root@SYL4 tmp]# ll
total 0
-rw-rw-r--. 1 tom  tom   0 Jul 14 18:17 1334
-rw-r--r--. 1 root root  0 Jul 14 17:35 abc
[root@SYL4 tmp]# [ -O abc ]
[root@SYL4 tmp]# echo $?
0
[root@SYL4 tmp]# [ -O 1334 ]
[root@SYL4 tmp]# echo $?
1
[root@SYL4 tmp]# 

测试文件是否存在并且默认组是否为当前用户组
[root@SYL4 tmp]# [ -G 1334 ]
[root@SYL4 tmp]# echo $?
1
[root@SYL4 tmp]# [ -G abc ]
[root@SYL4 tmp]# echo $?
0
[root@SYL4 tmp]# 
5.1

一、test命令的应用类型

1、判断表达式

if test (表达式为真)

if test !表达式为假

test 表达式1 –a 表达式2 两个表达式都为真

test 表达式1 –o 表达式2 两个表达式有一个为真

2、判断字符串

test –n 字符串 字符串的长度非零

test –z 字符串 字符串的长度为零

test 字符串1=字符串2 字符串相等

test 字符串1!=字符串2 字符串不等

3、判断整数

test 整数1 –eq 整数2 整数相等(equal)

test 整数1 –ge 整数2 整数1大于等于整数2(greater than or equal)

test 整数1 –gt 整数2 整数1大于整数2(greater than)

test 整数1 –le 整数2 整数1小于等于整数2(less than or equal)

test 整数1 –lt 整数2 整数1小于整数2(less than)

test 整数1 –ne 整数2 整数1不等于整数2(not equal)

4、判断文件

test File1 –ef File2 两个文件具有同样的设备号和i结点号

test File1 –nt File2 文件1比文件2(newer than)

test File1 –ot File2 文件1比文件2(older than)

test –b File 文件存在并且是块设备文件

test –c File 文件存在并且是字符设备文件

test –d File 文件存在并且是目录

test –e File 文件存在

test –f File 文件存在并且是正规文件

test –g File 文件存在并且是设置了组ID

test –G File 文件存在并且属于有效组ID

test –h File 文件存在并且是一个符号链接(-L)

test –k File 文件存在并且设置了sticky位

test –b File 文件存在并且是块设备文件

test –L File 文件存在并且是一个符号链接(-h)

test –o File 文件存在并且属于有效用户ID

test –p File 文件存在并且是一个命名管道

test –r File 文件存在并且可读

test –s File 文件存在并且是一个套接字

test –t FD 文件描述符是在一个终端打开的

test –u File 文件存在并且设置了它的set-user-id位

test –w File 文件存在并且可写

test –x File 文件存在并且可执行

二、就用举例

这里举一个略微复杂点的例子吧,如下:

if [ "$version" != " " -a "$version" != "$old_version" ];then

……………………

fi

本例第一处用于检测$version参数是否为空,使用"!=",此处使用了字符串的判读。后面的-a,使用判读表达式,要求前面的判读和后面的判都为真,才会执行后面的语句。该表达式还等价于下面的表达式:if [ "$version" != " " ] && [ "$version" != "$old_version" ];then

……………………

fi

注意:-a是在方括号内,而&& 是在方括号外。另外注意上面的方括号和直接test命令都可以使用的,不过习惯上用方括号表示。不要遇到test -d file1这样的语句而不认识。
6. 组合测试条件
-a      //与关系   &&
-o      //或关系   ||
!       //非关系   not

[ $# -gt 1 -a $# -le 3 ]
哪个参数大于1且哪个参数小于等于3
[ $# -gt 1 ] && [ $# -le 3 ]


[root@SYL4 ~]# [ 2 -gt 3 -a 'abc' == 'abc' ]
[root@SYL4 ~]# echo $?
1
[root@SYL4 ~]# [ 2 -gt 3 ] && [ 'abc' == 'abc' ]
[root@SYL4 ~]# echo $?
1
[root@SYL4 ~]# 

[root@SYL4 ~]# [ 2 -gt 3 -o 'abc' == 'abc' ]
[root@SYL4 ~]# echo $?
0
[root@SYL4 ~]# [ 2 -gt 3 ] || [ 'abc' == 'abc' ]
[root@SYL4 ~]# echo $?
0
[root@SYL4 ~]# 

[root@SYL4 ~]# [ ! 2 -gt 3 -o 'abc' == 'abc' ]
[root@SYL4 ~]# echo $?
0          
[root@SYL4 ~]# [ ! 2 -gt 3 -a 'abc' == 'abc' ]
[root@SYL4 ~]# echo $?
0
[root@SYL4 ~]#           
[root@SYL4 ~]# ! [ 2 -gt 3 -o 'abc' == 'abc' ]
[root@SYL4 ~]# echo $?
1
[root@SYL4 ~]# ! [ 2 -gt 3 -a 'abc' == 'abc' ]
[root@SYL4 ~]# echo $?
0
[root@SYL4 ~]# 
7. 条件判断,控制结构
if 如果
then 然后
fi 完成   finish
elif 如果
else 否则  
7.1 单分支if语句
如果判断条件成立,否则....
如果判断条件不成立,否则什么也不做
if 判断条件(成立与否); then
    statement1
    statement2
    ......
fi                   
7.2 双分支if语句
if 判断条件; then
    statement1
    statement2
    ......
else
    statement3
    statement4
    ......
fi  
7.3 多分支if语句
if 判断条件1; then
    statement1
    statement2
    ......
elif 判断条件2; then
    statement3
    statement4
    ......
else
    statement5
    statement6
    ......
fi  
7.4 用户输入
[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

read -p " 请输入apache安装目录路径:" install_dir
echo $install_dir
[root@SYL4 ~]# ./test.sh 
 请输入apache安装目录路径:/usr/local/apache 
/usr/local/apache
[root@SYL4 ~]# ./test.sh 
 请输入apache安装目录路径:

[root@SYL4 ~]# 

[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

read -p " 请输入apache安装目录路径:" install_dir
if [ -z $install_dir ];then
    install_dir=/opt/apache
fi
echo $install_dir
[root@SYL4 ~]# ./test.sh 
 请输入apache安装目录路径:/usr/local/apache
/usr/local/apache
[root@SYL4 ~]# ./test.sh 
 请输入apache安装目录路径:
/opt/apache
[root@SYL4 ~]#     

让用户输入自己的年龄,计算其还能活多少年,假定每人能活100年
[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

read -p " 请输入您的年龄:" age
echo "您还有" $[100 - $age] "年寿命 " 
[root@SYL4 ~]# ./test.sh 
 请输入您的年龄:44
您还有 56 年寿命 
[root@SYL4 ~]# 
7.5 if条件判断
用户登录验证

[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

read -p " 请输入您的用户名:" username
read -p " 请输入您的密码:" password

if [ $username == "mushuang" ] && [ $password == "run123" ];then
    echo "欢迎" $username
else
    echo "用户名和密码不正确"
fi
[root@SYL4 ~]# ./test.sh 
 请输入您的用户名:kkk
 请输入您的密码:dd
用户名和密码不正确
[root@SYL4 ~]# 
[root@SYL4 ~]# ./test.sh 
 请输入您的用户名:mushuang
 请输入您的密码:run123
欢迎 mushuang
[root@SYL4 ~]# 
  
  
  
在程序里设定好一个数字,然后启动程序让用户猜,用户输入后,根据他的输入提示用户输入的是否正确,如果错误,提示是猜大了还是猜小了
[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

read -p " 请猜数字:" number

if [ $number -eq 15 ];then
    echo "恭喜你,猜对了"
elif [ $number -gt 15 ];then
    echo "猜大了"
else
    echo "猜小了"
fi
[root@SYL4 ~]# ./test.sh 
 请猜数字:50
猜大了
[root@SYL4 ~]# ./test.sh 
 请猜数字:10
猜小了
[root@SYL4 ~]# ./test.sh 
 请猜数字:15
恭喜你,猜对了
[root@SYL4 ~]#  
    
    
[root@SYL4 ~]# echo $RANDOM
32606
[root@SYL4 ~]# echo $RANDOM
12722
[root@SYL4 ~]#     

二. 分支选择

case $变量名 in            
value1)   //变量的值             
    statement    //执行的任务,命令            
    ...                
    ;;            
value2)  //变量的值              
    statement                
    ...                
    ;;            
*)    //除了value1和value2的其他的命令            
    statement                
    ...                
    ;;        
esac

//case支持glob风格的通配符:
    *           //任意长度任意字符
    ?           //任意单个字符
    []          //指字范围内的任意单个字符
    abc|bcd     //abc或bcd

例1,httpd的执行脚本,控制服务,简易
$1 外面传的参数
[root@SYL4 ~]# vim /etc/init.d/httpd 
[root@SYL4 ~]# cat /etc/init.d/httpd
#!/bin/bash

case $1 in
    start|START)
        echo "starting httpd..."
        ;;
    stop|STOP)
        echo "stopping httpd..."
        ;;
    restart|RESTART)
        echo "restarting httpd..."
        ;;
    status|STSTUS)
        echo "show status..."
        ;;
    *)
        echo "Usage: service httpd start|stop|restart|status"
        ;;
esac
[root@SYL4 ~]# service httpd start
starting httpd...
[root@SYL4 ~]# service httpd status
show status...
[root@SYL4 ~]# service httpd stop
stopping httpd...
[root@SYL4 ~]# service httpd restart
restarting httpd...
[root@SYL4 ~]# service httpd ddd
Usage: service httpd start|stop|restart|status
[root@SYL4 ~]# service httpd START
starting httpd...



例2,输入数字,查看月份
[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

printf "Input integer number: " //输入整数
read num

case $num in
    1)
        echo "Monday"
        ;;
    2)
        echo "Tuesday"
        ;;
    3)
        echo "Wednesday"
        ;;
    4)
        echo "Thursday"
        ;;
    5)
        echo "Friday"
        ;;
    6)
        echo "Saturday"
        ;;
    7)
        echo "Sunday"
        ;;
    *)
        echo "error"
esac
[root@SYL4 ~]# ./test.sh 
Input integer number: 2
Tuesday
[root@SYL4 ~]# ./test.sh 
Input integer number: 5
Friday
[root@SYL4 ~]# 


例3,输入字母,标点,数字各打印英文单词
[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

printf "Input a character: "//输入一个字符
read -n 1 char

case $char in
    [a-zA-Z])
        printf "\nletter\n"
        ;;
    [0-9])
        printf "\nDigit\n"
        ;;
    [,.?!])
        printf "\nPunctuation\n"
        ;;
    *)
        printf "\nerror\n"
esac
[root@SYL4 ~]# ./test.sh 
Input a character: a
letter 字母
[root@SYL4 ~]# ./test.sh 
Input a character: 0
Digit 数字
[root@SYL4 ~]# ./test.sh 
Input a character: .
Punctuation 标点符号
[root@SYL4 ~]# ./test.sh 
Input a character: @
error 错误
[root@SYL4 ~]# 

三. 循环语句

  • 循环语句通常需要有一个进入条件和一个退出条件。

  • 1. i是个变量 ((i=0;i<=10;i++))
    i++  原来的基础上+1跟i+=1等同
    i--  原来的基础上-1
    当i=0
    i+=2 原来的基础上+2
    
    2. seq用法
    [root@SYL4 ~]# seq 2 5 15
    2
    7
    12
    [root@SYL4 ~]# seq 10
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [root@SYL4 ~]# 
    
1. for循环
  • for循环当列表不为空时进入循环,否则退出循环
for 变量 in 列表; do
    循环体
done


  
for ((expr1;expr2;expr3))
{
    循环体
}

  
  
  
for (( expr1 ; expr2 ; expr3 ));do
    循环体
done

    
    
    
expr1   //用于指定初始条件,给控制变量一个初始值
expr2   //判定什么时候退出循环
expr3   //修正expr1指定的变量的值

//如何生成列表:
    {1..100}
    seq [起始数] [步进长度] 结束数
  • 示例
1.
从$(seq 10)这个结果一次取一个值赋予i这个变量,结果打出来

[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

for i in $(seq 10);do
    echo $i
    echo ===
done
[root@SYL4 ~]# ./test.sh 
1
===
2
===
3
===
4
===
5
===
6
===
7
===
8
===
9
===
10
===
[root@SYL4 ~]# 

2.
[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

for (( i=1;i<=10;i++))
{
    echo $i
    echo =+=+
}
[root@SYL4 ~]# ./test.sh 
1
=+=+
2
=+=+
3
=+=+
4
=+=+
5
=+=+
6
=+=+
7
=+=+
8
=+=+
9
=+=+
10
=+=+
[root@SYL4 ~]# 

  
3.
[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

for (( i=1;i<=10;i++));do
    echo $i
    echo ===
done
[root@SYL4 ~]# ./test.sh 
1
===
2
===
3
===
4
===
5
===
6
===
7
===
8
===
9
===
10
===
[root@SYL4 ~]#
    
3. 创建10位用户,并且设置密码
[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

for i in $(seq 10);do
    id user$i
    if [ $? -ne 0 ];then
    useradd user$i
    fi
    echo '123456'|passwd --stdin user$i
done
[root@SYL4 ~]# ./test.sh 
id: 'user1': no such user
Changing password for user user1.
passwd: all authentication tokens updated successfully.
id: 'user2': no such user
Changing password for user user2.
passwd: all authentication tokens updated successfully.
id: 'user3': no such user
Changing password for user user3.
passwd: all authentication tokens updated successfully.
id: 'user4': no such user
Changing password for user user4.
passwd: all authentication tokens updated successfully.
id: 'user5': no such user
Changing password for user user5.
passwd: all authentication tokens updated successfully.
id: 'user6': no such user
Changing password for user user6.
passwd: all authentication tokens updated successfully.
id: 'user7': no such user
Changing password for user user7.
passwd: all authentication tokens updated successfully.
id: 'user8': no such user
Changing password for user user8.
passwd: all authentication tokens updated successfully.
id: 'user9': no such user
Changing password for user user9.
passwd: all authentication tokens updated successfully.
id: 'user10': no such user
Changing password for user user10.
passwd: all authentication tokens updated successfully.
[root@SYL4 ~]# id user10
uid=1011(user10) gid=1011(user10) groups=1011(user10)
[root@SYL4 ~]# 

4. 清掉密码
[root@SYL4 ~]# passwd -d user5
Removing password for user user5.
passwd: Success
[root@SYL4 ~]#  
        
5.
[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

for i in {1..5};do
    id user$i
    if [ $? -ne 0 ];then
    useradd user$i
    fi
    echo '123456'|passwd --stdin user$i
done
[root@SYL4 ~]# ./test.sh 
uid=1002(user1) gid=1002(user1) groups=1002(user1)
Changing password for user user1.
passwd: all authentication tokens updated successfully.
uid=1003(user2) gid=1003(user2) groups=1003(user2)
Changing password for user user2.
passwd: all authentication tokens updated successfully.
uid=1004(user3) gid=1004(user3) groups=1004(user3)
Changing password for user user3.
passwd: all authentication tokens updated successfully.
uid=1005(user4) gid=1005(user4) groups=1005(user4)
Changing password for user user4.
passwd: all authentication tokens updated successfully.
uid=1006(user5) gid=1006(user5) groups=1006(user5)
Changing password for user user5.
passwd: all authentication tokens updated successfully.
[root@SYL4 ~]#         
2. while循环
  • while循环适用于循环次数未知的场景,注意要有退出条件。
  • 不知道循环多少次的时候使用
  • 条件满足时进入循环,条件不满足了退出循环。
2.1 while循环正常用法
while 条件; do
    statement
    ...
done
  • 示例
[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

i=1
while [ $i -le 10 ];do
    echo $i
    echo ----
    let i++
done
[root@SYL4 ~]# ./test.sh 
1
----
2
----
3
----
4
----
5
----
6
----
7
----
8
----
9
----
10
----
[root@SYL4 ~]# 
2.2 while循环特殊用法
//while循环特殊用法一:死循环
while :;do
    statement
    ...
done

//这里的冒号可以改成任何非空值

      
while循环特殊用法二:逐行读取某文件,将值存入line变量中
while read line;do
    statement
    ...
done < /path/to/somefile
  • 示例
1. 死循环
[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

i=1
while :;do
    echo $i
    echo ----
    let i++
    sleep 5
done
[root@SYL4 ~]# ./test.sh 
1
----
2
----
3
----
^C
[root@SYL4 ~]# 

2. i+=2
[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

i=1
while :;do
    echo $i
    echo ----
    let i+=2
    sleep 2
done
[root@SYL4 ~]# ./test.sh 
1
----
3
----
5
----
7
----
^C
[root@SYL4 ~]# 

3. 死循环,大于10停止,break//大于10循环终止 
[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

i=0

while :;do
    echo $i
    echo ----
    let i+=2
    if [ $i -gt 10 ];then
        break//大于10循环终止
    fi
done
[root@SYL4 ~]# ./test.sh 
0
----
2
----
4
----
6
----
8
----
10
----
[root@SYL4 ~]#         
2.2.1 特殊用法二,示例
  • 写一个脚本,要求如下:
    • 设定变量Fa的值为/etc/passwd
    • 依次向/etc/passwd中的每个用户问好,并且说出对方的ID是什么。结果输出如下:
      • Hello,root,your UID is 0.
    • 统计当前系统一个有多少个用户并输出
[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

Fa=/etc/passwd
count=0

while read line;do
    user=$(echo $line | awk -F: '{print $1}')
    uid=$(echo $line | awk -F: '{print $3}')
    echo "Hello,$user,your UID is $uid."
    let count++
done < $Fa

echo "当前系统一个有$count个用户."
[root@SYL4 ~]# ./test.sh 
Hello,root,your UID is 0.
Hello,bin,your UID is 1.
Hello,daemon,your UID is 2.
Hello,adm,your UID is 3.
Hello,lp,your UID is 4.
Hello,sync,your UID is 5.
Hello,shutdown,your UID is 6.
Hello,halt,your UID is 7.
Hello,mail,your UID is 8.
Hello,operator,your UID is 11.
Hello,games,your UID is 12.
Hello,ftp,your UID is 14.
Hello,nobody,your UID is 65534.
Hello,dbus,your UID is 81.
Hello,systemd-coredump,your UID is 999.
Hello,systemd-resolve,your UID is 193.
Hello,tss,your UID is 59.
Hello,polkitd,your UID is 998.
Hello,unbound,your UID is 997.
Hello,sssd,your UID is 996.
Hello,sshd,your UID is 74.
Hello,redhat,your UID is 1000.
Hello,tom,your UID is 1001.
Hello,apache,your UID is 995.
Hello,user1,your UID is 1002.
Hello,user2,your UID is 1003.
Hello,user3,your UID is 1004.
Hello,user4,your UID is 1005.
Hello,user5,your UID is 1006.
Hello,user6,your UID is 1007.
Hello,user7,your UID is 1008.
Hello,user8,your UID is 1009.
Hello,user9,your UID is 1010.
Hello,user10,your UID is 1011.
当前系统一个有34个用户.
[root@SYL4 ~]# 
3. until循环
  • 条件不满足时进入循环,条件满足了退出循环。
until 条件; do
    statement
    ...
done
4. 循环语句特殊情况
4.1 在循环语句中,有几种特别情况:
  • break [num] :提前退出循环。当循环语句中出现break时,将提前退出循环,不再执行循环后面的语句

  • continue [num]继续 ,提前结束本轮循环而进入下一轮循环。当循环语句执行到continue时,continue后面的语句将不再执行,提前进入下一轮循环

1. break终止
[root@SYL4 ~]# vim test.sh
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

i=0

while :;do
    if [ $i -gt 10 ];then
        break
    fi
    echo $i
    let i++
    sleep 1
done
[root@SYL4 ~]# ./test.sh 
0
1
2
3
4
5
6
7
8
9
10
[root@SYL4 ~]# 

2.continue 继续,没有退出的条件,一直执行
[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

i=0

while :;do
    if [ $i -gt 10 ];then
        continue      
    fi
    echo $i
    let i++
    sleep 1
done
[root@SYL4 ~]# ./test.sh 
0
1
2
3
4
5
6
7
8
9
10

3.
[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# ./test.sh 
11
12
13
14
15
16
17
18
19
20
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

i=11

while :;do
    if [ $i -lt 10 ];then
        continue      
    elif [ $i -gt 20 ];then
        break
    fi
    echo $i
    let i++
    sleep 1
done
[root@SYL4 ~]# 

4.  
[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

i=0

while :;do
    let i++
    if [ $i -lt 10 ];then
        continue      
    elif [ $i -gt 20 ];then
        break
    fi
    echo $i
done
[root@SYL4 ~]# ./test.sh 
10
11
12
13
14
15
16
17
18
19
20
[root@SYL4 ~]#

5.    
[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

i=0

while :;do
    let i+=2
    if [ $i -lt 10 ];then
        continue      
    elif [ $i -gt 20 ];then
        break
    fi
    echo $i
done
[root@SYL4 ~]# ./test.sh 
10
12
14
16
18
20
[root@SYL4 ~]#                         

四. 定义脚本退出状态码

//exit命令用于定义执行状态结果

exit #      //此处的#号是一个数字,其范围可以是0-255

如果脚本没有明确定义退出状态码,那么,最后执行的一条命令的退出码即为脚本的退出状态码

注意:脚本中一旦遇到exit命令,脚本会立即终止
  • 脚本最后一条命令执行成功
[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

i=0
[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

i=0

while :;do
    let i+=2
    if [ $i -lt 10 ];then
        continue      
    elif [ $i -gt 20 ];then
        break
    fi
    echo $i
done
exit 200
[root@SYL4 ~]# ./test.sh 
10
12
14
16
18
20
[root@SYL4 ~]# echo $?
200
[root@SYL4 ~]# 
  • 查看最后一条命令,最后一条命令成功,脚本成功否则失败
[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# ./test.sh 
10
12
14
16
18
20
./test.sh: line 14: ihjn: command not found
[root@SYL4 ~]# echo $?
127
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

i=0

while :;do
    let i+=2
    if [ $i -lt 10 ];then
        continue      
    elif [ $i -gt 20 ];then
        break
    fi
    echo $i
done
ihjn
[root@SYL4 ~]# 
1. 位置变量shift
  • shift [num],位置变量使用完以后退出,后面的参数向前推进
[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

for i in $*;do
    echo $1
    shift 1
done
[root@SYL4 ~]# ./test.sh a 1 2 3 4 5 6
a
1
2
3
4
5
6
[root@SYL4 ~]# 

推2个  
[root@SYL4 ~]# vim test.sh 
[root@SYL4 ~]# cat test.sh 
#!/bin/bash

for i in $*;do
    echo $1
    shift 2
done
[root@SYL4 ~]# ./test.sh 1 2 3 4 5 6 7 8 9
1
3
5
7
9
9
9
9
9
[root@SYL4 ~]#   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值