2. shell script判断

3.3判断

3.1利用test命令测试

1.关于某个档名的『文件类型』判断,如 test -e filename 表示存在否

测试的标志 代表意义
-e 该文件名是否存在?(常用)
-f 该文件名是否存在且为档案(file)?(常用)
-d 该『文件名』是否存在且为目录(directory)?(常用)
-b 该文件名是否存在且为一个 block device 装置?
-c 该文件名是否存在且为一个 character device 装置?
-S 该文件名是否存在且为一个 Socket 档案?
-p 该文件名是否存在且为一个 FIFO (pipe) 档案?
-L 该文件名是否存在且为一个连结档?

2.关于档案的权限侦测,如 test -r filename 表示可读否 (但 root 权限常有例外)

测试的标志 代表意义
-r 侦测该档名是否存在且具有『可读』的权限?
-w 侦测该档名是否存在且具有『可写』的权限?
-x 侦测该档名是否存在且具有『可执行』的权限?
-u 侦测该文件名是否存在且具有『SUID』的属性?
-g 侦测该文件名是否存在且具有『SGID』的属性?
-k 侦测该文件名是否存在且具有『Sticky bit』的属性?
-s 侦测该档名是否存在且为『非空白档案』?

3.两个档案之间的比较,如: test file1 -nt file2

测试的标志 代表意义
-nt (newer than)判断 file1 是否比 file2 新
-ot (older than)判断 file1 是否比 file2 旧
-ef 判断 file1 与 file2 是否为同一档案,可用在判断 hard link 的判定上。 主要意义在判定,两个档案是否均指向同一个 inode 哩!

4.关于两个整数之间的判定,例如 test n1 -eq n2

测试的标志 代表意义
-eq 两数值相等 (equal)
-ne 两数值不等 (not equal)
-gt n1 大于 n2 (greater than)
-lt n1 小于 n2 (less than)
-ge n1 大于等于 n2 (greater than or equal)
-le n1 小于等于 n2 (less than or equal)

5.判定字符串的数据

测试的标志 代表意义
test -z string 判定字符串是否为 0 ?若 string 为空字符串,则为 true
test -n string 判定字符串是否非为 0 ?若 string 为空字符串,则为 false。 注: -n 亦可省略
test str1 = str2 判定 str1 是否等于 str2 ,若相等,则回传 true
test str1 != str2 判定 str1 是否不等于 str2 ,若相等,则回传 false

6.多重条件判定,例如: test -r filename -a -x filename

测试的标志 代表意义
-a (and)两状况同时成立!例如 test -r file -a -x file,则 file 同时具有 r 与 x 权限时,才回传 true。
-o (or)两状况任何一个成立!例如 test -r file -o -x file,则 file 具有 r 或 x 权限时,就可回传 true。
! 反相状态,如 test ! -x file ,当 file 不具有 x 时,回传 true

写一个脚本,要求如下:

这个档案是否存在,若不存在则给予一个『Filename does not exist』的讯息,并中断程序;

若这个档案存在,则判断他是个档案或目录,结果输出『Filename is regular file』或 『Filename is directory』

判断一下,执行者的身份对这个档案或目录所拥有的权限,并输出权限数据!

[sam] vi sh05.sh
#!/bin/bash
# Program:
#  User input a filename ,program will check the flowing:
#  1.)exist?  2.)file/directory?  3.)file permissions
# History:
#2014/07/22 Sam  First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
# 1. 让使用者输入档名,并且判断使用者是否真的有输入字符串?
echo -e "Please input a filename, I will check the filename's type and \
permission. \n\n"
read -p "Input a filename : " filename
test -z $filename && echo "You MUST input a filename." && exit 0
# 2. 判断档案是否存在?若不存在则显示讯息并结束脚本
test ! -e $filename && echo "The filename '$filename' DO NOT exist" && exit 0
# 3. 开始判断文件类型与属性
test -f $filename && filetype="regulare file"
test -d $filename && filetype="directory"
test -r $filename && perm="readable"
test -w $filename && perm="$perm writable"
test -x $filename && perm="$perm executable"
# 4. 开始输出信息!
echo "The filename: $filename is a $filetype"
echo "And the permissions are : $perm"

如果你执行这个脚本后,他会依据你输入的档名来进行检查喔!先看是否存在,再看为档案或目录类型,最后判断权限。 但是你必须要注意的是,由于 root 在很多权限的限制上面都是无效的,所以使用 root执行这个脚本时, 常常会发现与 ls -l 观察到的结果并不相同!所以,建议使用一般使用者来执行这个脚本试看看。 不过你必须要使用 root 的身份先将这个脚本搬移给使用者就是了,不然一般用户无法进入 /root 目录的。 很有趣的例子吧!你可以自行再以其他的案例来撰写一下可用的功能呢!

3.2利用判断符号[ ]

在中括号 [] 内的每个组件都需要有空格键来分隔;

在中括号内的变数,最好都以双引号括号起来; 在中括号内的常数,最好都以单或双引号括号起来。

[sam] vi sh06.sh

#!/bin/bash
#Program:
#   This program shows the user's choice
#History:
#2014/07/22  Sam First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

read -p "Please input (Y/N) :" yn
[ "$yn" == "Y" -o "$yn" == "y" ] && echo "OK,continue" && exit 0   #-o表示或的意思
[ "$yn" == "N" -o "$yn" == "n" ] && echo "Oh,interrupt!" &&exit 0  #&&表示前面真,后面为真
echo "I don't know what your choice is" && exit 0

3.3shell script 的默认变量($0,$1…)

执行的脚本档名为 $0 这个变量,第一个接的参数就是 $1 啊

/path/to/scriptname opt1 opt2 opt3 opt4
$0 $1 $2 $3 $4
$# :代表后接的参数『个数』,以上表为例这里显示为『 4 』;
$@ :代表『 "$1" "$2" "$3" "$4" 』之意,每个变量是独立的(用双引号括起来);
$* :代表『 "$1c$2c$3c$4" 』,其中 c 为分隔字符,默认为空格键, 所以本例中代表『 "$1 $2 $3 $4"』之意。

[sam] vi sh07.sh

#!/bin/bash
#Program:
#   Program shows the script name .parameters...
#History:
#  2014/07/22  Sam  First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

echo "The script name is ==> $0"
echo "Total parameter number is ==> $#"
[ "$#" -lt 2 ] && echo "The number of parameter is less than 2. Stop here." && exit 0
echo "Your whole parameter is ==> '$@'"
echo "The 1st parameter ==> $1"
echo "The 2nd parameter ==> $2"

执行结果如下:

[root@www scripts]# sh sh07.sh theone haha quot
The script name is ==> sh07.sh <==檔名 Total parameter number is ==> 3 <==果然有三个参数 Your whole parameter is ==> 'theone haha quot' <==参数的内容全部 The 1st parameter ==> theone <==第一个参数 The 2nd parameter ==> haha <==第二个参数

Shift 造成参数变量号码的偏移

[sam] vi sh08.sh

#!/bin/bash
#Program:
#   Program shows the effect of shift function.
#History:
#  2014/07/22  Sam First realease
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo "Total parameter number is ==> $#"
echo "Your whole parameter is   ==> '$@'"
shift   # 进行第一次『一个变量的 shift 』
echo "Total parameter number is ==> $#"
echo "Your whole parameter is   ==> '$@'"
shift 3 # 进行第二次『三个变量的 shift 』
echo "Total parameter number is ==> $#"
echo "Your whole parameter is   ==> '$@'"
这玩意的执行成果如下:
[root@www scripts]# sh sh08.sh one two three four five six <==给予六个参数 Total parameter number is ==> 6   <==最原始的参数变量情况 Your whole parameter is ==> 'one two three four five six'
Total parameter number is ==> 5   <==第一次偏移,看底下发现第一个 one 不见了 Your whole parameter is ==> 'two three four five six'
Total parameter number is ==> 2   <==第二次偏移掉三个,two three four 不见了 Your whole parameter is ==> 'five six'

光看结果你就可以知道啦,那个 shift 会移动变量,而且 shift 后面可以接数字,代表拿掉最前面的几个参数的意思。 上面的执行结果中,第一次进行 shift 后他的显示情况是『 one two three four five six』,所以就剩下五个啦!第二次直接拿掉三个,就变成『 two three four five six 』啦! 这样这个案例可以了解了吗?理解了 shift 的功能了吗?

参考资料:

http://linux.vbird.org/linux_basic/0340bashshell-scripts.php

个人公众号,比较懒,很少更新,可以在上面提问题:

更多精彩,请移步公众号阅读:

Sam avatar
About Sam
专注生物信息 专注转化医学