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 ] 2 与 2 是否相等
[root@SYL4 ~]# echo $?
0 条件成立
是否不等:
[root@SYL4 ~]# [ 2 -ne 2 ] 2与2是否不相等
[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 ~]#