Linux 之 shell script -- 善用判断式

正是因为我们可以通过程序脚本,设计逻辑交给计算机帮助人类处理问题,才有了如今发展壮大的CS产业。shell script作为一个小程序语言,也是可以加入各种逻辑的,今天学习如何在shell script中加入判断式(很简单的)~~

首先,要学习一些逻辑判断符号:这里通过如下“test指令的测试功能”学习,里面一些逻辑判断(例如-o,-a)是不局限于test的,可以在shell中灵活应用。

1.test指令的测试功能

1.1 关于某个档名的“文本类型”判断

teat -e filename 表示filename存在与否

测试的标志 代表意义
-e 该档名是否存在?
-f 该档名是否存在且为文件(file)?
-d 该文件名是否存在且为目录(directory)?
-b 该档名是否存在且为一个block device装置?
-c 该档名是否存在且为一个character device装置?
-S 该档名是否存在且为一个Socket文件?
-p 该档名是否存在且为一个FIFO(pipe)文件?
-L 该档名是否存在且为一个链接档?
1.2关于文件的权限侦测

test -r filename 表示filename是否可读

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

test file1 -nt file2 判断file1是否比file2新

测试的标志 代表意义
- nt (newer than)判断file1是否比file2新
-ot (older than) 判断file 1 是否比file2 旧
-ef 判断 file1 与 file 2 是否为同一文件,可用在判断hard link的判定上。主要意义在判定,两个文件是否均指向同一个inode。
1.4 关于两个整数之间的判定

test n1 -eq n2 判断n1是否等于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)
1.5 判定字符串的数据
测试的标志 代表意义
test -z string 判定字符串是否为0?若string为空字符串,则为true
test -n string 判定字符串是否非?若string为空字符串,则为false(-n亦可省略)
test str1 == str2 判定str1是否等于str2,若相等,则回传true
test str1 != str2 判定str1 是否不等于 str2,若相等,则回传false
1.6多重条件判定

test -r filename -a -x filename 判断filename是否可读且可执行

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

我们写个简单的例子(注意利用test , ||, &&):

  • 1)这个文件是否存在,若不存在则给予一个“filename does not exist” 的讯息,并中断程序;
  • 2)若这个文件存在,则判断他是文件还是目录?结果输出“filename is a regular file” 或 “filename is directory”;
  • 3)判断一下,执行者的身份对这个文件或目录所拥有的权限,并输出权限数据

先看一下这个 low low的写法。。。

#!/bin/bash
read -p "请输入文件名:" filename
test -e ${filename} && echo "exist" || echo "Not exist"
test -f ${filename} && echo "It is a file" || echo "It is not a file"
test -d ${filename} && echo "It is a directory" || echo "It is not a directory"
test -r ${filename} && echo "you can read " || echo "you can not read"
test -w ${filename} && echo "you can write " || echo "you can not write"
test -x ${filename} && echo "you can execute" || echo "you can not execute"

再看一下鸟哥的高端表达~~
vi file_perm.sh 输入如下代码:

#!/bin/bash
#1.让使用者输入档名,并且判断使用者是否真的有输入字符串?
echo -e "Please input a filename, I will check the filename's type and permission"
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 permission for you are : ${perm}"

2. 利用判断括号[ ]

中括号[ ]学到现在可能有点眼花缭乱了, 因为之前学通配符和正则表达式时都有遇到过。

而在bash的语法中使用它作为shell的判断式时,必须注意中括号的两端要有空格符来分隔!如果空格键用来表示。那么,这些地方都应该注意加空格键:

Linux 之 shell script -- 善用判断式_第1张图片
判断括号注意事项

写一段shell来练习:

  • 1)当执行一个程序的时候,这个程序会让用户选择Y或N,
  • 2)如果用户输入Y或y时,就显示“OK,continue”
  • 3)如果用户输入N或n时,就显示“Oh,interrupt!”
  • 4)如果不是Y/y/N/n之内的其他字符,就显示"I don't konw what your choice is"

Tip:
-- 这里判断式内要有2个判断才行,因此判断式内的判断连结需要使用-o
-- 同时,巧用exit 0来控制程序执行

vi ans_yn.sh 输入如下代码:

#!/bin/bash
read -p "Please input 'Y' or  'N' to execute this program:" input
[ "${input}" == "Y" -o "${input}" == "y" ] && echo "OK,continue" && exit 0 #如果输入"Y" 或 “y”,echo输出后便退出程序
[ "${input}" == "N" -o "${input}" == "n" ] && echo "Oh,interrupt!"  && exit 0 #如果输入"N" 或 “n”,echo输出后便退出程序
echo "I don't know what your choice is" && exit 0 #如果不是"Y","y","N","n"中的任何一个,程序才会走到这一步(这是前面两步判断式后面加`exit 0`的意义)

3. shell script 的默认变数

3.1 认识shell script 的默认变数($0,$1)

其实script针对参数已经有设定好一些变量名称了


script针对参数已经设定好一些变量名称

执行的脚本档名为$0这个变量,第一个接的参数就是$1。所以,只要我们在script里面善用$1的话,就可以很简单的立即下达某些指令功能了。
其他一些较为特殊的变量可以在script内使用来呼叫这些参数:

  • $# 代表后接的参数(个数)
  • $@ 代表 「“$1” “$2” “$3” “$4”」之意,每个变量是独立的(用双括号括起来)
  • $* 代表 「“$1c$2c$3c$4”」,其中c为分隔字符,默认为空格键,所以本例中代表「“$1 $2 $3 $4”」之意

还是来实例学习一下吧:执行一个可以携带参数的script,执行脚本后可以显示如下内容

  • 1)程序的文件名为何?
  • 2)共有几个参数?
  • 3)若参数的个数小于2则告知使用者参数数量太少
  • 4)全部的参数内容为何
  • 5)第一个参数为何
  • 6)第二个参数为何

vi how_paras.sh 输入如下代码:

#!/bin/bash
echo "程序的文件名为 ==> "$0""
echo "程序的参数个数 ==> "$#""
[ "$#" -lt 2 ] && echo "参数的个数小于2"
echo "全部的参数内容 ==> "$@""
echo "第一个参数为 ==> "$1""
echo "第二个参数为 ==> "$2""

3.2 shift:造成参数变量号码偏移

shift会移动变量,而且shif 后面可以接数字,代表拿掉最前面的几个参数的意思
还是从例子中理解吧
vim shift_paras.sh 输入如下代码:

#!/bin/bash
echo "程序的参数个数 ==> “$#”"
echo "全部的参数内容 ==> “$@”"
shift #第一次偏移(1个参数)
echo "程序的参数个数 ==> “$#”"
echo "全部的参数内容 ==> “$@”"
shift 3 #第二次偏移(3个参数)
echo "程序的参数个数 ==> “$#”"
echo "全部的参数内容 ==> “$@”"

执行shift_paras.sh,看鸟哥执行的结果吧

Linux 之 shell script -- 善用判断式_第2张图片
学习bash中的shift

你可能感兴趣的:(Linux 之 shell script -- 善用判断式)