第十三章、学习 Shell Scripts 条件判断式


利用 if .... then


  • 单层、简单条件判断式
if [ 条件判断式 ]; then
	当条件判断式成立时,可以进行的命令工作内容;
fi   <==将 if 反过来写,就成为 fi !结束 if 之意!
  • && 代表 AND ;
  • || 代表 or ;

[ "$yn" == "Y" -o "$yn" == "y" ]
上式可替换为
[ "$yn" == "Y" ] || [ "$yn" == "y" ]

[[email protected] scripts]# cp sh06.sh sh06-2.sh  <==用改的比较快!
[[email protected] scripts]# vi sh06-2.sh
#!/bin/bash
# Program:
#       This program shows the user‘s choice
# History:
# 2005/08/25    VBird   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

if [ "$yn" == "Y" ] || [ "$yn" == "y" ]; then
	echo "OK, continue"
	exit 0
fi
if [ "$yn" == "N" ] || [ "$yn" == "n" ]; then
	echo "Oh, interrupt!"
	exit 0
fi
echo "I don‘t know what your choice is" && exit 0

  • 多重、复杂条件判断式
# 一个条件判断,分成功进行与失败进行 (else)
if [ 条件判断式 ]; then
	当条件判断式成立时,可以进行的命令工作内容;
else
	当条件判断式不成立时,可以进行的命令工作内容;
fi
# 多个条件判断 (if ... elif ... elif ... else) 分多种不同情况运行
if [ 条件判断式一 ]; then
	当条件判断式一成立时,可以进行的命令工作内容;
elif [ 条件判断式二 ]; then
	当条件判断式二成立时,可以进行的命令工作内容;
else
	当条件判断式一与二均不成立时,可以进行的命令工作内容;
fi
[[email protected] scripts]# cp sh06-2.sh sh06-3.sh
[[email protected] scripts]# vi sh06-3.sh
#!/bin/bash
# Program:
#       This program shows the user‘s choice
# History:
# 2005/08/25    VBird   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

if [ "$yn" == "Y" ] || [ "$yn" == "y" ]; then
	echo "OK, continue"
elif [ "$yn" == "N" ] || [ "$yn" == "n" ]; then
	echo "Oh, interrupt!"
else
	echo "I don‘t know what your choice is"
fi

一般来说,如果你不希望使用者由键盘输入额外的数据时, 让使用者在下达命令时就将参数带进去! 现在我们想让使用者输入『 hello 』这个关键字时,利用参数的方法可以这样依序设计:

  1. 判断 $1 是否为 hello,如果是的话,就显示 "Hello, how are you ?";
  2. 如果没有加任何参数,就提示使用者必须要使用的参数下达法;
  3. 而如果加入的参数不是 hello ,就提醒使用者仅能使用 hello 为参数。

整个程序的撰写可以是这样的:

[[email protected] scripts]# vi sh09.sh
#!/bin/bash
# Program:
#	Check $1 is equal to "hello"
# History:
# 2005/08/28	VBird	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

if [ "$1" == "hello" ]; then
	echo "Hello, how are you ?"
elif [ "$1" == "" ]; then
	echo "You MUST input parameters, ex> {$0 someword}"
else
	echo "The only parameter is ‘hello‘, ex> {$0 hello}"
fi

netstat命令可以查询到目前主机有开启的网络服务端口 (service ports)

[[email protected] ~]# netstat -tuln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address     Foreign Address   State
tcp        0      0 0.0.0.0:111       0.0.0.0:*         LISTEN
tcp        0      0 127.0.0.1:631     0.0.0.0:*         LISTEN
tcp        0      0 127.0.0.1:25      0.0.0.0:*         LISTEN
tcp        0      0 :::22             :::*              LISTEN
udp        0      0 0.0.0.0:111       0.0.0.0:*
udp        0      0 0.0.0.0:631       0.0.0.0:*
#封包格式           本地IP:端口       远程IP:端口       是否监听

上面的重点是『Local Address (本地主机的IP与端口对应)』那个栏位,他代表的是本机所启动的网络服务!若为 127.0.0.1 则是仅针对本机开放,若是 0.0.0.0 或 ::: 则代表对整个 Internet 开放。 每个端口 (port) 都有其特定的网络服务,几个常见的 port 与相关网络服务的关系是:

  • 80: WWW
  • 22: ssh
  • 21: ftp
  • 25: mail
  • 111: RPC(远程程序呼叫)
  • 631: CUPS(列印服务功能)

假设我的主机有兴趣要侦测的是比较常见的 port 21, 22, 25及 80 时,那我如何透过 netstat 去侦测我的主机是否有开启这四个主要的网络服务端口呢?由於每个服务的关键字都是接在冒号『 : 』后面, 所以可以藉由撷取类似『 :80 』来侦测的!那我就可以简单的这样去写这个程序喔:

[[email protected] scripts]# vi sh10.sh
#!/bin/bash
# Program:
# 	Using netstat and grep to detect WWW,SSH,FTP and Mail services.
# History:
# 2005/08/28	VBird	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

# 1. 先作一些告知的动作而已~
echo "Now, I will detect your Linux server‘s services!"
echo -e "The www, ftp, ssh, and mail will be detect! \n"

# 2. 开始进行一些测试的工作,并且也输出一些资讯罗!
testing=$(netstat -tuln | grep ":80 ")   # 侦测看 port 80 在否?
if [ "$testing" != "" ]; then
	echo "WWW is running in your system."
fi
testing=$(netstat -tuln | grep ":22 ")   # 侦测看 port 22 在否?
if [ "$testing" != "" ]; then
	echo "SSH is running in your system."
fi
testing=$(netstat -tuln | grep ":21 ")   # 侦测看 port 21 在否?
if [ "$testing" != "" ]; then
	echo "FTP is running in your system."
fi
testing=$(netstat -tuln | grep ":25 ")   # 侦测看 port 25 在否?
if [ "$testing" != "" ]; then
	echo "Mail is running in your system."
fi

由於日期是要用相减的方式来处置,所以我们可以透过使用 date 显示日期与时间,将他转为由 1970-01-01 累积而来的秒数, 透过秒数相减来取得剩余的秒数后,再换算为日数即可。整个脚本的制作流程有点像这样:

  1. 先让使用者输入他们的退伍日期;
  2. 再由现在日期比对退伍日期;
  3. 由两个日期的比较来显示『还需要几天』才能够退伍的字样。

利用『 date --date="YYYYMMDD" +%s 』转成秒数后,接下来的动作就容易的多了!如果你已经写完了程序,对照底下的写法试看看:

[[email protected] scripts]# vi sh11.sh
#!/bin/bash
# Program:
#	You input your demobilization date, I calculate how many days
#	before you demobilize.
# History:
# 2005/08/29	VBird	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

# 1. 告知使用者这支程序的用途,并且告知应该如何输入日期格式?
echo "This program will try to calculate :"
echo "How many days before your demobilization date..."
read -p "Please input your demobilization date (YYYYMMDD ex>20090401): " date2

# 2. 测试一下,这个输入的内容是否正确?利用正规表示法
date_d=$(echo $date2 |grep ‘[0-9]\{8\}‘)   # 看看是否有八个数字
if [ "$date_d" == "" ]; then
	echo "You input the wrong date format...."
	exit 1
fi

# 3. 开始计算日期
declare -i date_dem=`date --date="$date2" +%s`    # 退伍日期秒数
declare -i date_now=`date +%s`                    # 现在日期秒数
declare -i date_total_s=$(($date_dem-$date_now))  # 剩余秒数统计
declare -i date_d=$(($date_total_s/60/60/24))     # 转为日数
if [ "$date_total_s" -lt "0" ]; then              # 判断是否已退伍
	echo "You had been demobilization before: " $((-1*$date_d)) " ago"
else
	declare -i date_h=$(($(($date_total_s-$date_d*60*60*24))/60/60))
	echo "You will demobilize after $date_d days and $date_h hours."
fi

利用 case ..... esac 判断

case  $变量名称 in   <==关键字为 case ,还有变量前有钱字号
  "第一个变量内容")   <==每个变量内容建议用双引号括起来,关键字则为小括号 )
	程序段
	;;            <==每个类别结尾使用两个连续的分号来处理!
  "第二个变量内容")
	程序段
	;;
  *)                  <==最后一个变量内容都会用 * 来代表所有其他值
	不包含第一个变量内容与第二个变量内容的其他程序运行段
	exit 1
	;;
esac                  <==最终的 case 结尾!『反过来写』!
[[email protected] scripts]# vi sh09-2.sh
#!/bin/bash
# Program:
# 	Show "Hello" from $1.... by using case .... esac
# History:
# 2005/08/29	VBird	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

case $1 in
  "hello")
	echo "Hello, how are you ?"
	;;
  "")
	echo "You MUST input parameters, ex> {$0 someword}"
	;;
  *)   # 其实就相当於万用字节,0~无穷多个任意字节之意!
	echo "Usage $0 {hello}"
	;;
esac

/etc/init.d/syslog restart

一般来说,使用『 case $变量 in 』这个语法中,当中的那个『 $变量 』大致有两种取得的方式:

  • 直接下达式:例如上面提到的,利用『 script.sh variable 』 的方式来直接给予 $1 这个变量的内容,这也是在 /etc/init.d 目录下大多数程序的设计方式。
  • 互动式:透过 read 这个命令来让使用者输入变量的内容。

让使用者能够输入 one, two, three ,
并且将使用者的变量显示到萤幕上,如果不是 one, two, three 时,就告知使用者仅有这三种选择。

[[email protected] scripts]# vi sh12.sh
#!/bin/bash
# Program:
#	This script only accepts the flowing parameter: one, two or three.
# History:
# 2005/08/29	VBird	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

echo "This program will print your selection !"
# read -p "Input your choice: " choice # 暂时取消,可以替换!
# case $choice in                      # 暂时取消,可以替换!
case $1 in                             # 现在使用,可以用上面两行替换!
  "one")
	echo "Your choice is ONE"
	;;
  "two")
	echo "Your choice is TWO"
	;;
  "three")
	echo "Your choice is THREE"
	;;
  *)
	echo "Usage $0 {one|two|three}"
	;;
esac

利用 function 功能

function fname() {
	程序段
}

因为 shell script 的运行方式是由上而下,由左而右, 因此在 shell script 当中的 function 的配置一定要在程序的最前面, 这样才能够在运行时被找到!

[[email protected] scripts]# vi sh12-2.sh
#!/bin/bash
# Program:
#	Use function to repeat information.
# History:
# 2005/08/29	VBird	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

function printit(){
	echo -n "Your choice is "     # 加上 -n 可以不断行继续在同一行显示
}

echo "This program will print your selection !"
case $1 in
  "one")
	printit; echo $1 | tr ‘a-z‘ ‘A-Z‘  # 将参数做大小写转换!
	;;
  "two")
	printit; echo $1 | tr ‘a-z‘ ‘A-Z‘
	;;
  "three")
	printit; echo $1 | tr ‘a-z‘ ‘A-Z‘
	;;
  *)
	echo "Usage $0 {one|two|three}"
	;;
esac
   

function 也是拥有内建变量的,
函数名称代表示 $0 ,而后续接的变量也是以 $1, $2...

[[email protected] scripts]# vi sh12-3.sh
#!/bin/bash
# Program:
#	Use function to repeat information.
# History:
# 2005/08/29	VBird	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

function printit(){
	echo "Your choice is $1"   # 这个 $1 必须要参考底下命令的下达
}

echo "This program will print your selection !"
case $1 in
  "one")
	printit 1  # 请注意, printit 命令后面还有接参数!
	;;
  "two")
	printit 2
	;;
  "three")
	printit 3
	;;
  *)
	echo "Usage $0 {one|two|three}"
	;;
esac


 

时间: 2024-10-22 18:08:29

第十三章、学习 Shell Scripts 条件判断式的相关文章

鸟哥的Linux私房菜_基础版_学习笔记9:第十三章 学习 Shell Scripts

13.1 什么是 Shell scripts 13.1.1 干嘛学习 shell scripts 13.1.2 第一支 script 的撰写与运行 在 shell script 的撰写中还需要用到底下的注意事项: 命令的运行是从上而下.从左而右的分析与运行: 命令的下达就如同第五章内提到的: 命令.选项与参数间的多个空白都会被忽略掉: 空白行也将被忽略掉,并且 [tab] 按键所推开的空白同样视为空白键: 如果读取到一个 Enter 符号 (CR) ,就尝试开始运行该行 (或该串) 命令: 至於

shell编程 条件判断式----利用 case ..... esac 判断

条件判断式----利用 case ..... esac 判断 case  $变量名称 in   <==关键词为 case ,还有变量前有钱字号 "第一个变量内容")   <==每个变量内容建议用双引号括起来,关键词则为小括号 ) 程序段 ;;            <==每个类别结尾使用两个连续的分号来处理! "第二个变量内容") 程序段 ;; *)                  <==最后一个变量内容都会用 * 来代表所有其它值 不包含

shell编程 条件判断式----利用 if .... then ----多重

条件判断式----利用 if .... then ----多重 在同一个数据的判断中,如果该数据需要进行多种不同的判断时,应该怎么作?举例来说,上面的 sh06.sh 脚本中,我们只要进行一次 $yn 的判断就好 (仅进行一次 if ),不想要作多次 if 的判断. 此时你就得要知道底下的语法了: # 一个条件判断,分成功进行与失败进行 (else) if [ 条件判断式 ]; then 当条件判断式成立时,可以进行的指令工作内容: else 当条件判断式不成立时,可以进行的指令工作内容: fi

shell编程-条件判断式

条件判断式主要有以下6种类型: [[email protected] test]# ls -l total 8 drwxr-xr-x 2 root root 4096 Jan 17 19:28 shell -rw-r--r-- 1 root root 4 Jan 17 19:29 test.sh [[email protected] test]# [ -d test.sh ] && echo "yes" || echo "no" no [[email

【shell】条件判断式

条件判断式的表示格式: 文件判断式: [[email protected] ~]# [ -e /root/1 ] && echo yes || echo no #注意[]里面的空格,第一个命令为真打印yes,否则打印no yes [[email protected] ~]# [ -f /root/1 ] && echo yes || echo no yes [[email protected] ~]# [ -d /root/1 ] && echo yes |

Linux学习 -- Shell编程 -- 条件判断

按照文件类型进行判断 两种格式 test -e /root/install.log [ -e /root/install.log ]   注意空格  适合用于脚本中 echo $?可以看到结果 [ -d /root ] && echo yes || echo no 按照文件权限进行判断 两个文件之间进行比较 eg.   [ test.txt -ef test.txt.hard ] && echo yes || echo no 两个整数之间比较 两个字符串之间比较 多重条件判

第十三章、学习 Shell Scripts

1. 什么是 Shell Script 1.1 干嘛学习 shell scripts 1.2 第一支 script 的撰写与运行 1.3 撰写 shell script 的良好习惯创建 2. 简单的 shell script 练习 2.1 简单范例: 对谈式脚本, 随日期变化, 数值运算 2.2 script 的运行方式差异 (source, sh script, ./script) 3. 善用判断式 3.1 利用 test 命令的测试功能 3.2 利用判断符号 [ ] 3.3 Shell sc

鸟哥的Linux私房菜——第十六章:学习Shell Scripts

视频链接: 1. 什么是 Shell Script       (shell写的脚本)1.1 干嘛学习 shell scripts? ()1.2 第一支 script 的撰写与执行1.3 撰写 shell script 的良好习惯建立 2. 简单的 shell script 练习: (read -p  date)3. 善用判断式:3.1 利用 test 指令的测试功能3.2 利用判断符号 [ ] 3.3 Shell script 的预设变数($0, $1...)4. 条件判断式:4.1 利用 i

SHELL学习笔记----IF条件判断,判断条件

SHELL学习笔记----IF条件判断,判断条件 前言: 无论什么编程语言都离不开条件判断.SHELL也不例外.  if list then           do something here       elif list then           do another thing here       else          do something else here fi  EX1: #!/bin/bash if [ `uname -m` == "x86_64" ]