shell scripts笔记(linux脚本) 条件判断

if … then

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

括号与括号之间,则以 && 或 || 来隔开,他们的意义是:
&& 代表 AND ;
|| 代表 or ;

范例 if…then

[dmtsai@study bin]$ cp ans_yn.sh ans_yn-2.sh <==用复制来修改的比较快!
[dmtsai@study bin]$ vim ans_yn-2.sh
#!/bin/bash
#Program:
#This program shows the user’s choice
#History:
#2015/07/16 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 [ “ y n " = = " Y " ] ∣ ∣ [ " {yn}" == "Y" ] || [ " yn"=="Y"]["{yn}” == “y” ]; then
echo “OK, continue”
exit 0
fi
if [ “ y n " = = " N " ] ∣ ∣ [ " {yn}" == "N" ] || [ " 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
elif 也是个判断式,因此出现 elif 后面都要接 then 来处理!
当条件判断式二成立时,可以进行的指令工作内容;
else
当条件判断式一与二均不成立时,可以进行的指令工作内容;
fi

利用参数的方法可以这样依序设计:

  1. 判断 $1 是否为 hello ,如果是的话,就显示 “Hello, how are you ?” ;
  2. 如果没有加任何参数,就提示使用者必须要使用的参数下达法;
  3. 而如果加入的参数不是 hello ,就提醒使用者仅能使用 hello 为参数。
    整个程序的撰写可以是这样的:
    [dmtsai@study bin]$ vim hello-2.sh
    #!/bin/bash
    #Program:
    #Check KaTeX parse error: Expected 'EOF', got '#' at position 23: …ual to "hello" #̲History: #2015/…{1}" == “hello” ]; then
    echo “Hello, how are you ?”
    elif [ “KaTeX parse error: Expected '}', got 'EOF' at end of input: …rameters, ex> {{0} someword}”
    else
    echo “The only parameter is ‘hello’, ex> {${0} hello}”
    fi

几个常见的 port 与相关网络服务的关系是:
80: WWW
22: ssh
21: ftp
25: mail
111: RPC (远端程序调用)
631: CUPS (打印服务功能)

如何通过 netstat 去侦测我的主机是否有打开这四个主要的网络服务端口 port 21, 22, 25 及 80
可以通过以下的程序:
[dmtsai@study bin]$ vim netstat.sh
#!/bin/bash
#Program:
#Using netstat and grep to detect WWW,SSH,FTP and Mail services.
#History:
#2015/07/16 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 ( smtp ) will be detect! \n”
#2. 开始进行一些测试的工作,并且也输出一些信息啰!
testfile=/dev/shm/netstat_checking.txt
netstat -tuln > KaTeX parse error: Expected 'EOF', got '#' at position 12: {testfile} #̲ 先转存数据到内存当中!不用一… ( grep “:80 " KaTeX parse error: Expected 'EOF', got '#' at position 14: {testfile} ) #̲ 侦测看 port 80 在否…{testing}” != “” ]; then
echo “WWW is running in your system.”
fi
testing=$ ( grep “:22 " KaTeX parse error: Expected 'EOF', got '#' at position 14: {testfile} ) #̲ 侦测看 port 22 在否…{testing}” != “” ]; then
echo “SSH is running in your system.”
fi
testing=$ ( grep “:21 " KaTeX parse error: Expected 'EOF', got '#' at position 14: {testfile} ) #̲ 侦测看 port 21 在否…{testing}” != “” ]; then
echo “FTP is running in your system.”
fi
testing=$ ( grep “:25 " KaTeX parse error: Expected 'EOF', got '#' at position 14: {testfile} ) #̲ 侦测看 port 25 在否…{testing}” != “” ]; then
echo “Mail is running in your system.”
fi

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

  1. 先让使用者输入他们的退伍日期;
  2. 再由现在日期比对退伍日期;
  3. 由两个日期的比较来显示 “ 还需要几天 ” 才能够退伍的字样。
    [dmtsai@study bin]$ vim cal_retired.sh
    #!/bin/bash
    #Program:
    #You input your demobilization date, I calculate how many days before you demobilize.
    #History:
    #2015/07/16 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>20150716 ) : " date2
    #2. 测试一下,这个输入的内容是否正确?利用正则表达式啰~
    date_d=$ ( echo KaTeX parse error: Expected 'EOF', got '#' at position 30: …'[0-9]\{8\}' ) #̲ 看看是否有八个数字 if […{date_d}” == “” ]; then
    echo “You input the wrong date format…”
    exit 1
    fi
    #3. 开始计算日期啰~
    declare -i date_dem=$ ( date --date=" d a t e 2 " + d e c l a r e − i d a t e n o w = {date2}" +%s ) # 退伍日期秒数 declare -i date_now= date2"+declareidatenow= ( date +%s ) # 现在日期秒数
    declare -i date_total_s=$ (( d a t e d e m − {date_dem}- datedem{date_now} )) # 剩余秒数统计
    declare -i date_d=$ (( KaTeX parse error: Expected 'EOF', got '#' at position 28: …s}/60/60/24 )) #̲ 转为日数 if [ "{date_total_s}" -lt “0” ]; then # 判断是否已退伍
    echo "You had been demobilization before: " $ (( -1* d a t e d ) ) " a g o " e l s e d e c l a r e − i d a t e h = {date_d} )) " ago" else declare -i date_h= dated"ago"elsedeclareidateh= (( $ (( d a t e t o t a l s − {date_total_s}- datetotals{date_d}6060*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 结尾!“反过来写”思考一下!

范例
[dmtsai@study bin]$ vim hello-3.sh
#!/bin/bash
#Program:
#Show “Hello” from $1… by using case … esac
#History:
#2015/07/16 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
case KaTeX parse error: Expected '}', got 'EOF' at end of input: …rameters, ex> {{0} someword}"
;;

  • ) # 其实就相当于万用字符,0~无穷多个任意字符之意!
    echo “Usage ${0} {hello}”
    ;;
    esac

使用者能够输入 one, two, three , 并且将使用者的变量显示到屏幕
上,如果不是 one, two, three 时,就告知使用者仅有这三种选择。
[dmtsai@study bin]$ vim show123.sh
#!/bin/bash
#Program:
#This script only accepts the flowing parameter: one, two or three.
#History:
#2015/07/17 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 () {
程序段
}

自订一个名为 printit 的函数来使用喔:
[dmtsai@study bin]$ vim show123-2.sh
#!/bin/bash
#Program:
#Use function to repeat information.
#History:
#2015/07/17 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 fname () { 程序段 } ” 内的 $0, $1… 等等与 shell script 的 $0 是不同的。

[dmtsai@study bin]$ vim show123-3.sh
#!/bin/bash
#Program:
#Use function to repeat information.
#History:
#2015/07/17 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

while do done, until do done (不定循环)

一般来说,不定循环最常见的就是下面这两种状态了:

while [ condition ] <==中括号内的状态就是判断式
do <==do 是循环的开始!
程序段落
done <==done 是循环的结束

while 的中文是 “ 当 … 时 ” ,所以,这种方式说的是 “ 当 condition 条件成立时,就进行循环,直到 condition 的条件不成立才停止 ” 的意思。

还有另外一种不定循环的方式:
until [ condition ]
do
程序段落
done

这种方式恰恰与 while 相反,它说的是 “ 当 condition 条件成立时,就终止循环, 否则就持续进行循环的程序段。

以 while 简单的练习:
[dmtsai@study bin]$ vim yes_to_stop.sh
#!/bin/bash
#Program:
#Repeat question until user input correct answer.
#History:
#2015/07/17 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
while [ “ y n " ! = " y e s " − a " {yn}" != "yes" -a " yn"!="yes"a"{yn}” != “YES” ]
do
read -p "Please input yes/YES to stop this program: " yn
done
echo “OK! you input the correct answer.”

如果使用 until 呢?呵呵有趣啰~ 他的条件会变成这样:
[dmtsai@study bin]$ vim yes_to_stop-2.sh
#!/bin/bash
#Program:
#Repeat question until user input correct answer.
#History:
#2015/07/17 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
until [ “ y n " = = " y e s " − o " {yn}" == "yes" -o " yn"=="yes"o"{yn}” == “YES” ]
do
read -p "Please input yes/YES to stop this program: " yn
done
echo “OK! you input the correct answer.”

for…do…done (固定循环)
语法是:
for var in con1 con2 con3 …
do
程序段
done

有三种动物,分别是 dog, cat, elephant 三种, 我想每一行都输出这样: “There are dogs…” 之类的字
样,则可以:
[dmtsai@study bin]$ vim show_animal.sh
#!/bin/bash
#Program:
#Using for … loop to print 3 animals
#History:
#2015/07/17 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
for animal in dog cat elephant
do
echo "There are ${animal}s… "
done

使用者输入某个目录文件名, 然后我找出某目录内的文件名的权限,该如何是好?
可以这样做啦~

[dmtsai@study bin]$ vim dir_perm.sh
#!/bin/bash
#Program:
#User input dir name, I find the permission of files.
#History:
#2015/07/17 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
#1. 先看看这个目录是否存在啊?
read -p “Please input a directory: " dir
if [ “ d i r " = = " " − o ! − d " {dir}" == "" -o ! -d " dir"==""o!d"{dir}” ]; then
echo “The KaTeX parse error: Expected 'EOF', got '#' at position 47: …em." exit 1 fi #̲2. 开始测试文件啰~ fil… ( ls ${dir} ) # 列出所有在该目录下的文件名称
for filename in f i l e l i s t d o p e r m = " " t e s t − r " {filelist} do perm="" test -r " filelistdoperm=""testr"{dir}/KaTeX parse error: Expected 'EOF', got '&' at position 13: {filename}" &̲& perm="{perm} readable”
test -w “ d i r / {dir}/ dir/{filename}” && perm=” p e r m w r i t a b l e " t e s t − x " {perm} writable" test -x " permwritable"testx"{dir}/KaTeX parse error: Expected 'EOF', got '&' at position 13: {filename}" &̲& perm="{perm} executable"
echo "The file d i r / {dir}/ dir/{filename}'s permission is ${perm} "
done

for…do…done 的数值处理
语法如下:
for (( 初始值 ; 限制值 ; 执行步阶 ))
do
程序段
done
这种语法适合于数值方式的运算当中

以这种方式来进行 1 累加到使用者输入的循环
[dmtsai@study bin]$ vim cal_1_100-2.sh
#!/bin/bash
#Program:
#Try do calculate 1+2+…+KaTeX parse error: Expected 'EOF', got '#' at position 14: {your_input} #̲History: #2015/…{nu}; i=i+1 ))
do
s=$ (( s + {s}+ s+{i} ))
done
echo “The result of ‘1+2+3+…+${nu}’ is ==> ${s}”

搭配乱数与阵列的实验

每天吃饭吃啥问题:
[dmtsai@study bin]$ vim what_to_eat.sh
#!/bin/bash
#Program:
#Try do tell you what you may eat.
#History:
#2015/07/17 VBird First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
eat[1]=" 卖当当漢堡包 " # 写下你所收集到的店家!
eat[2]=" 肯爷爷炸鸡 "
eat[3]=" 彩虹日式便当 "
eat[4]=" 越油越好吃大雅 "
eat[5]=" 想不出吃啥学餐 "
eat[6]=" 太师父便当 "
eat[7]=" 池上便当 "
eat[8]=" 怀念火车便当 "
eat[9]=" 一起吃方便面 "
eatnum=9 # 需要输入有几个可用的餐厅数!
check=$ (( ${RANDOM} * ${eatnum} / 32767 + 1 ))
echo “your may eat KaTeX parse error: Expected '}', got 'EOF' at end of input: {eat[{check}]}”

如果想要每次都秀出 3 个店家呢? 而且这个店家不能重复喔!重复当然就没啥意义了!
所以,你可以这样做

	[dmtsai@study bin]$  vim what_to_eat-2.sh
	#!/bin/bash
	#Program:
	#Try do tell you what you may eat.
	#History:
	#2015/07/17 VBird First release
	PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
	export PATH
	eat[1]=" 卖当当漢堡包 "
	eat[2]=" 肯爷爷炸鸡 "
	eat[3]=" 彩虹日式便当 "
	eat[4]=" 越油越好吃大雅 "
	eat[5]=" 想不出吃啥学餐 "
	eat[6]=" 太师父便当 "
	eat[7]=" 池上便当 "
	eat[8]=" 怀念火车便当 "
	eat[9]=" 一起吃方便面 "
	eatnum=9
	eated=0
	while [ "${eated}" -lt 3 ]; do
	check=$ (( ${RANDOM} * ${eatnum} / 32767 + 1  ))
	mycheck=0
	if [ "${eated}" -ge 1 ]; then
	for i in $ ( seq 1 ${eated}  )
	do
	if [ ${eatedcon[$i]} == $check ]; then
	mycheck=1
	fi
	done
	fi
	if [ ${mycheck} == 0 ]; then
	echo "your may eat ${eat[${check}]}"
	eated=$ (( ${eated} + 1  ))
	eatedcon[${eated}]=${check}
	fi
	done

shell script 的追踪与 debug

判断shell脚本执行有没有问题
[dmtsai@study ~]$ sh [-nvx] scripts.sh
选项与参数:
-n :不要执行 script,仅查询语法的问题;
-v :再执行 sccript 前,先将 scripts 的内容输出到屏幕上;
-x :将使用到的 script 内容显示到屏幕上,这是很有用的参数!

范例一:测试 dir_perm.sh 有无语法的问题?
[dmtsai@study ~]$ sh -n dir_perm.sh
#若语法没有问题,则不会显示任何信息!

范例二:将 show_animal.sh 的执行过程全部列出来~
[dmtsai@study ~]$ sh -x show_animal.sh

  • PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/root/bin
  • export PATH
  • for animal in dog cat elephant
  • echo 'There are dogs… ’
    There are dogs…
  • for animal in dog cat elephant
  • echo 'There are cats… ’
    There are cats…
  • for animal in dog cat elephant
  • echo 'There are elephants… ’
    There are elephants…

之前一直提到的 /etc/init.d/netconsole ,这个 script 是干嘛用的? 利用 vim
去查阅最前面的几行字,他出现如下信息:
#netconsole This loads the netconsole module with the configured parameters.
#chkconfig: - 50 50
#description: Initializes network console logging
#config: /etc/sysconfig/netconsole
意思是说,这个脚本在设置网络终端机来应付登陆的意思,且配置文件在 /etc/sysconfig/netconsole 设置内! 所以,你写的脚本如果也能够很清楚的交待,那就太棒了!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值