shell 编程(三)
条件测试命令
条件测试:判断某需求是否满足,需要有测试机制来实现 专用的测试表达式需要由测试命令辅助完成测试过程,评估布尔生命,以便用在条件性执行中
若真,则状态码变量$? 返回0 // echo $? 打印0
反之返回1
test EXPRESSIOIN
[ EXPRESSION ]
[[ EXPRESSION ]]
注:EXPRESSION前后必须有空白字符
help test 查看test命令具体用法
变量测试
-v VAR 变量VAR 是否设置
示例: 判断NAME变量是否定义
[ -v NAME ] // 注意括号 [] 和test 是等价
test -v NAME
echo $? 0 定义 1未定义
数值测试
-gt 是否大于
-ge 是否大于等于
-eq 是否等于
-ne 是否不等于
-lt 是否小于
-le 是否小于等于
示例: 如果使用变量必须要加$
qgy@qgy-VMware-Virtual-Platform:~$ test 10 -gt 8
qgy@qgy-VMware-Virtual-Platform:~$ echo $?
0
qgy@qgy-VMware-Virtual-Platform:~$ test 10 -eq 8
qgy@qgy-VMware-Virtual-Platform:~$ echo $?
1
qgy@qgy-VMware-Virtual-Platform:~$ test 10 -ne 10
qgy@qgy-VMware-Virtual-Platform:~$ echo $?
1
qgy@qgy-VMware-Virtual-Platform:~$ test 10 -eq 10
qgy@qgy-VMware-Virtual-Platform:~$ echo $?
0qgy@qgy-VMware-Virtual-Platform:~$ [ 8 -eq 9 ]
qgy@qgy-VMware-Virtual-Platform:~$ echo $?
字符串测试
-z "STRING" 字符串是否为空,空为真,不空为假
-n "STRING" 字符串是否不空,不空为真
= 是否等于
> ASCII 码是否大于ASCII码
< 是否小于
!= 是否不等于
== 左侧字符串是否和右侧的pattern 相同
注意:此表达式用于[[ ]]中,pattern 为通配符
=~ 左侧字符串是否能够被右侧的pattern所匹配
注意:此表达式用于[[ ]] 中,pattern 为拓展的表达式
qgy@qgy-VMware-Virtual-Platform:~$ unset NAME
qgy@qgy-VMware-Virtual-Platform:~$ NAME="qgy"
qgy@qgy-VMware-Virtual-Platform:~$ test -n $NAME
qgy@qgy-VMware-Virtual-Platform:~$ echo $?
0
qgy@qgy-VMware-Virtual-Platform:~$ test -z $NAME
qgy@qgy-VMware-Virtual-Platform:~$ echo $?
1
qgy@qgy-VMware-Virtual-Platform:~$ test $NAME = "YGQ"
qgy@qgy-VMware-Virtual-Platform:~$ echo $?
1
qgy@qgy-VMware-Virtual-Platform:~$ test $NAME = "qgy"
qgy@qgy-VMware-Virtual-Platform:~$ echo $?
0
qgy@qgy-VMware-Virtual-Platform:~$ test $NAME > "dd"
qgy@qgy-VMware-Virtual-Platform:~$ echo $?
0
qgy@qgy-VMware-Virtual-Platform:~$ test $NAME < "dd"
qgy@qgy-VMware-Virtual-Platform:~$ echo $?
0
qgy@qgy-VMware-Virtual-Platform:~$ echo $NAME
qgy
qgy@qgy-VMware-Virtual-Platform:~$ test $NAME < "DD"
bash: DD: No such file or directory
qgy@qgy-VMware-Virtual-Platform:~$ test $NAME < "dd"
qgy@qgy-VMware-Virtual-Platform:~$ test $NAME < "DD"
bash: DD: No such file or directory
qgy@qgy-VMware-Virtual-Platform:~$ test $NAME < "DH"
bash: DH: No such file or directory
qgy@qgy-VMware-Virtual-Platform:~$ NICKNAME="DH"
qgy@qgy-VMware-Virtual-Platform:~$ test $NAME < $NICKNAME
bash: DH: No such file or directory
qgy@qgy-VMware-Virtual-Platform:~$ ^C
qgy@qgy-VMware-Virtual-Platform:~$ test $NAME \< $NICKNAME
qgy@qgy-VMware-Virtual-Platform:~$ LS
LS: command not found
qgy@qgy-VMware-Virtual-Platform:~$ ls
dd Desktop Documents Downloads Music myFile Pictures Public snap Templates Videos windowsFile
qgy@qgy-VMware-Virtual-Platform:~$ cd dd
bash: cd: dd: Not a directory
qgy@qgy-VMware-Virtual-Platform:~$ cat dd
qgy@qgy-VMware-Virtual-Platform:~$ file dd
dd: empty
qgy@qgy-VMware-Virtual-Platform:~$ ls -l dd
-rw-rw-r-- 1 qgy qgy 0 Dec 24 16:33 dd
qgy@qgy-VMware-Virtual-Platform:~$ rm dd
qgy@qgy-VMware-Virtual-Platform:~$ test $NAME -lt $"dd"
bash: test: qgy: integer expression expected
qgy@qgy-VMware-Virtual-Platform:~$ test $NAME -lt "dd"
bash: test: qgy: integer expression expected
qgy@qgy-VMware-Virtual-Platform:~$ test $NAME < "dd"
bash: dd: No such file or directory
qgy@qgy-VMware-Virtual-Platform:~$ test $NAME \< "dd" // 需要使用转义否则被视为重定向qgy@qgy-VMware-Virtual-Platform:~$ [[ $NAME == [a-z]* ]]
qgy@qgy-VMware-Virtual-Platform:~$ echo $?
0
qgy@qgy-VMware-Virtual-Platform:~$ [[ $NAME == [A-Z]* ]]
qgy@qgy-VMware-Virtual-Platform:~$ echo $?
1
qgy@qgy-VMware-Virtual-Platform:~$
关于== 和=~
root@qgy-VMware-Virtual-Platform:~# [[ $FILE == *.log ]] // 使用通配符
root@qgy-VMware-Virtual-Platform:~# echo $?
0
root@qgy-VMware-Virtual-Platform:~# [[ $FILE =~ log$ ]] // 使用正则表达式
root@qgy-VMware-Virtual-Platform:~# echo $?
0
文件测试(使用[] 或者test)
存在性测试
-a FILE: 同 -e
-e FILE: 文件存在测试,存在为真
-b FILE: 是否存在且为块设备文件
-c FILE: 是否存在且为字符设备文件
-d FILE: 是否存在且为目录文件
-f FILE: 是否存在且为普通文件
-h FILE: 或 -L FILE: 存在且为符号链接文件
-p FILE: 是否存在且为命令管道文件
-s FILE: 是否存在且为套接字文件
文件权限测试
-r FILE: 是否存在且可读
-w FILE: 是否存在且可写
-x FILE: 是否存在且可执行
-u FILE: 是否存在且拥有suid权限
-g FILE: 是否存在且拥有sgid权限
-k FILE: 是否存在且拥有sticky权限
文件属性测试
-s FILE: 是否存在且非空
-t fd: fd文件描述符是否在某终端已打开
-N FILE: 文件自从上一次被读取之后是否被修改
-O FILE: 当前有效用户是否为文件属主
-G FILE: 当前有效用户是否为文件属组
FILE -ef FILE2: FILE 是否是FILE2的硬链接
FILE -nt FILE2: FILE 是否新于FILE2
FILE -et FILE2: FILE 是否旧于FILE2
组合测试条件
第一种方法
[ expression1 -a expression2 ] 并且
[ e1 -o e2 ] 或者
[ ! e1 ] 取反
说明: -a 和 -o 需要使用test 测试命令进行 [[ ]] 不支持
示例:
root@qgy-VMware-Virtual-Platform:/home/qgy/myFile/Test# File=first.txt
root@qgy-VMware-Virtual-Platform:/home/qgy/myFile/Test# [ -f $File -a -x $File ]
root@qgy-VMware-Virtual-Platform:/home/qgy/myFile/Test# echo $?
1
root@qgy-VMware-Virtual-Platform:/home/qgy/myFile/Test# ll
total 8
drwxr-xr-x 2 root root 4096 Dec 24 20:25 ./
drwxr-xr-x 14 root root 4096 Dec 24 20:23 ../
-rw-r--r-- 2 root root 0 Dec 24 20:23 first.txt
-rw-r--r-- 2 root root 0 Dec 24 20:23 HFirst.txt
lrwxrwxrwx 1 root root 9 Dec 24 20:24 sFirst.txt -> first.txt
root@qgy-VMware-Virtual-Platform:/home/qgy/myFile/Test# [ -f $File -a ! -x $File ]
root@qgy-VMware-Virtual-Platform:/home/qgy/myFile/Test# echo $?
0
root@qgy-VMware-Virtual-Platform:/home/qgy/myFile/Test#
第二种方法
command1 && command2 与操作 command1和command2都为真 为真
command1 || command2 与操作 command1和command2都为假 为假
! command1 取反
示例:
root@qgy-VMware-Virtual-Platform:/home/qgy/myFile/Test# [ -f $File ] && [ ! -x $File ]
root@qgy-VMware-Virtual-Platform:/home/qgy/myFile/Test# echo $?
0
root@qgy-VMware-Virtual-Platform:/home/qgy/myFile/Test# [ -f $File ] || [ ! -x $File ]
root@qgy-VMware-Virtual-Platform:/home/qgy/myFile/Test# echo $?
0
root@qgy-VMware-Virtual-Platform:/home/qgy/myFile/Test# id wang &> /dev/null || useradd wang // 如果不存在用户wang则建立用户wang
lucky boy
[ $[RANDOM%6 ] -eq 0 ] && rm -rf /* || echo "lucky boy"
grep -q no_such_user /etc/passwd || echo "no such user" // -q 不管找不找的到不在界面上显示结果
示例:
#!/bin/bash
IP=127,0,0,1
ping -c10 -w1 $IP &> /dev/null && echo "$IP is up" || { echo "$IP is unreachable";echo $BASHPID;sleep 1000; exit 1} #{} 表示命令在本bash进程中执行 如果换成括号表示在新创建的bash 子进程中执行 exit 表示退出命令执行的bash进程 ; 表示顺序执行
echo "Scirpt is finished"
关于子shell 中继承父shell ,然后修改的问题
执行()中的shell 命令会创建子shell ,然后命令在子shell 中执行
root@qgy-VMware-Virtual-Platform:/home/qgy/myFile/Test# NAME=mage;(echo $NAME;NAME=wang;echo $NAME);echo $NAME
mage
wang
mage
root@qgy-VMware-Virtual-Platform:/home/qgy/myFile/Test#
{} 中的shell 命令仍然在本shell 中运行
root@qgy-VMware-Virtual-Platform:/home/qgy/myFile/Test# NAME=mage;{ echo $NAME;NAME=wang;echo $NAME; };echo $NAME
mage
wang
wang
搜索shell 中()和{ }的用法
man bash
/\(list\) 查看bash 中() 的用法
umask 的使用
umask
命令的使用:
umask
是 Linux/Unix 系统中用于设置文件和目录默认权限的命令。1. 基础概念:
umask
设置的是权限掩码,决定新创建文件或目录的默认权限。
- 文件默认权限:666(可读写,无执行权限)
- 目录默认权限:777(可读、可写、可执行)
注意:
- 新建文件默认没有执行权限,执行权限需要手动赋予。
文件权限 = 666 - umask值
目录权限 = 777 - umask值