shell脚本编程基础第二篇
read命令
使用read来把输入的值非配给一个或者多个shell变量,可以提示用户输入一些参数等,此时我们可以使用read命令来完成此功能
read
[选项] [名称]
read -p 指定要显示的提示信息
read -t 声明超时
注意:1
当我们写完一个脚本后,需要对脚本进行语法检查,如果发现语法不对,我们可以进行修改,
语法检测命令:bash -n
/path/to/some_scripts
2
完成语法测试后,还可以进行功能测试,可以说是调试,也可以加上执行权限后运行,可以通过bash所提供的调试功能来进行运行测试
运行调试命令:bash -x /path/to/some_scripts
read
从标准输入中读取值,给每一个单词分配一个变量,所有剩余的单词都被分配给最后一个变量
read -p "who ar you?:" file
流程控制
过程式编程语言:
顺序执行
按照顺序一条一条的语句执行
选择执行 按照条件进行选择执行
循环执行
按照给定的循环条件进行循环执行
其中的顺序执行不需要特定的控制,只需要按照语句依次执行即可;
选择执行,则需要特定的控制语句 例如
if、case 来判断选择执行;
循环执行,则需要特定的循环控制体来控制 例如 for、while
条件选择if语句
if语句可以嵌套
选择执行:
单分支:if 判断条件;then
语句开头
条件为真的分支代码
fi 语句结尾
双分支:if 判断条件;then 语句开头
条件为真的分支代码
else
条件为假的分支代码
fi 语句结尾
多分支结构:if 命令1;then
语句开头
if-true
elif
命令2;then
if-true
elif
命令3;then
if-true
else
all-false
fi 语句结尾
逐条件进行判断,第一次遇到为真条件时,执其他分支,而后结束真个if语句
条件判断:case语句
case 变量引用 in
模式1)
分支1 命令1
;;
模式2)
分支2
命令2
;;
*)
默认分支
;; 从上到下的进行判断条件
esac
ease 支持 glob风格的通配符
*
任意长度任意的字符
? 任意单个字符
[]
指定范围内的任意单个字符
a|b
a或b
shell 脚本
循环
循环执行 for , while , until
就是程序按照一定的条件反复进行执行相关操作,知道不在满足循环条件是结束,这里面的重点就是这个循环体
循环体包括两部分,循环的进入条件和循环的退出条件,两个部分必须同时存在 否则将无法进入循环内部,或者循环无法结束,导致系统崩溃
重复运行多少次:
循环次数事先已知
循环次数事先未知
for循环
for 变量名 in 列表;do
循环体
done
例如:
#!/bin/bash
#user:Compro
for i
in 1 2 3 4;do
echo "$i"
done
编辑脚本,i是定义的变量名称,1234 是变量的值,然后循环打印输出
执行机制:一次将列表中的元素赋值给“变量名”;每次赋值后即执行一次循环体;知道列表中的元素好近,循环才结束。
列表生成的方式:
1直接给出列表
2整数列表:
{start…end}
例如:{1..10}
seq start step end 例如:$(seq 1 2
10)
3返回列表的命令:
$(命令) 例如:$(ls
/var)
位置变量参数:在脚本中用于引用传递给脚本的参数
$1,$2,,${10},,
特殊变量:
$? 保存上一条命令的执行结果成功与否的状态,用数字来表示,0-255;
0表示成功,其他则为失败
$0 在脚本中用于引用传递脚本名称本身
$#
保存传递给当前脚本的参数的个数
$* 保存传递给当前脚本的所有参数
$@
保存传递给当前脚本的所有参数 两个在不同的地方用会产生不同的效果
练习
[root@localhost
~]# vim forrc.d.sh
#!/bin/bash
#user:Compro
# /etc/rc.d/rc3.d
目录下分别有多个以 K 开头和以 S 开头的
# 文件;分别读取每个文件,以 K 开头的文件输出为文件加 stop
# ,以 S
开头的文件输出为文件名加 start ;
for i in `ls /etc/rc.d/rc3.d`
循环定义i为变量名,in之后跟变量的值,也就是ls /etc/rc.d/rc3.d 查看目录的命令
do
filef1=`echo
$i |cut -c1` 定义变量名= 引用上面的变量名i 抽取内容开头第1列
case $filef1
in 条件判断,case语句,调用上面的变量filef1
K) 匹配大写K 然后才执行引用的变量值
echo -e
"$i\tstop" 输出引用变量后的结果 后缀加上tstop
;;
S) 匹配大写S 然后才执行引用的变量值
echo -e
"$i\tstart" 输出引用变量后的结果 后缀加上tstart
;;
*) 任意长度任意字符
echo "unkown
file"
;;
esac
done
[root@localhost ~]# vim
shuzizonghe.sh
#!/bin/bash
#user:Compro
#提示输入正整数n的值,计算1+2+3+4+…n的总和
read
-p 'please input the number:' n 说明信息,提示信息, 请输入数字
num=`echo $n |grep
"^[[:digit:]]\+$"` 定义变量名num = 调用$n的变量,查询开头是数字, \+匹配前面字符至少一次$行尾锚定
if
"$num";then 判断条件调用上面变量
if [
$num -eq 0 ];then 变量值是否等于0
echo "the umber is 0"
输入数字为0 则提示这数字为0
exit 并且退出,不再往下面条件判断
fi
else
echo "the number is negative"
如果输入的是负数就提示这条信息
fi
string=0
字符串=0
for i in `seq
$n`;do 定义变量名i 后面列表的seq调后$n的值
sum=$[$sum+$i] 定义变量名sum =调后变量 总计 + $i 的数值
string=$string+$1 字符串 = 输入的字符串 + 变量1
done
echo
"$string=$sum" 输出结果 为 输出的变量字符串=数值在原有的基础上相加
[root@localhost ~]# vim forip.sh
#!/bin/bash
#user:Compro
#
写一个脚本,提示请输入网络地址,如 192.168.0.0 ,判断输入的网段中主机在>线状态
#255.255.255.0
echo -n
"IP:" 提示输入IP
read IP 说明信息IP
ipdizi=`echo $IP | cut -d. -f1-3
`. 定义变量名称=调用$IP获取的值 抽取 以.为分隔符 1-3的字符
#
if echo $IP | egrep
'\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){2}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>'
&>/dev/null
then
ip地址扩展表达式
for i in `seq 200 210`
定义变量名i 列表内容为 seq 200 100 之间的数字
do
if ping -c 1 -W 1 $ipdizi$i
&> /dev/null 调用$ipdizi $i 的值 重定向到文件 不显示出来
then
echo -e "$ipdizi$i\tonline" 显示在线的IP
else
echo -e
"$ipdizi$i\toffline" 显示不在线的IP
fi
[root@localhost ~]# vim
for99.sh
#!/bin/bash
#uesr:Compro
#打印99乘法表
for i in `seq
9` 定义变量名i 列表内容为seq 9 生成1-9的数字的行
do
for o in `seq 1
$i` 定义变量名o 列表内容为 seq 1 $i 1循环到 $i变量值 第1行就打印1遍,第2行就打印2遍,,,
do
echo -ne "$i*$o=$(($i*$o))\t" $i的值*$o的值= $变量中的结果 ~]#
echo -ne "5*5=$((5*5))\t" 结果是25 \t 是在每一行 空白符隔开
done
echo
done
while 循环
while CONDITION;do
condition状态就是判断式
循环体 do是循环的开始
done
done是循环的结束
~]# i=1;while [ $i -le 9 ];do echo $i;let i++;done
当变量i的值1于等于9
循环打印,在原有的1上面做运算++。直到9为止
condition
循环控制条件;进入循环之前,先做一次判断,每一次循环之后会再次做判断;条件为‘true’ (真)则执行一次循环,知道条件测试状态为‘false’
(假)终止循环
因此:condition 一般应该有循环控制变量,而此变量的值会在循环体不断的被修正
进入条件 condition 为true 真
。 退出条件:condition为false 假
[root@localhost ~]# vim
while100.sh
#!/bin/bash
#
#user:Compro
#求100以内所有正整数之和
i=1 定义变量i的值=1
sum=0 sum=0
while [ $i -le
100 ];do $i 小于等于 100 就执行循环,
sum=$(expr $sum +
$i) $ 运算$sum + $i的值 定义为变量sum
let i++
i++ 递增运算 然后循环判断,直到判断i是否小于至等于100
done
echo $sum
[root@localhost ~]# vim
whileping.sh
#!/bin/bash
#
#user:Compro
#ping范围内的所有主机在线状态,统计在线主机和离线主机个多少个
a="10.1.252."
定义变量值,ip范围
b=1
最小1开始的值
c=0
d=0
while [ $b -le 10 ];do 判断循环条件 $b
是否小于等于 10 从1循环到10
ping -c1 -W1 $a$b &> /dev/null
ping的结果导入到别的文件中 不显示出来
if [ $? -eq 0 ];then 调用上面的值
判断是否等于0
echo "$a$b is yes" 如果成功,则打印yes
let
c++ c++ 递增运算 判断上面的结果随之递增
else
echo "$a$b is no" 如果上面的失败,判断为no
let
d++ d++ 递增运算 判断上面的结果随之递增
fi
let b++ 递增运算循环 ,
不加这个就了死循环,
done
echo "yes users is $c" 调用c的变量结果
统计了yes的次数
echo "no users is $d" 调用d的变量结果 统计了no的次数
[root@localhost ~]# vim whil99.sh
#!/bin/bash
#
#uesr:Compro
#打印99乘法表
s=1
定义变量s=1 s可以理解竖
while [ $s -le 9 ];do 判断条件循环,$s 小于等9
h=1 定义变量名h=1 可以理解行
while [ $h -le $s ];do 判断条i安,$h小于等于#s
shuzi=$[$s*$h] 数值=$s*$h的结果
echo -ne
"$s*$h=$shuzi\t" 输出显示上面的结果 \t 空格隔开
let
h++ 递增运算 $h 的结果 执行9遍
done
echo
let s++ 递增运算 $s 的结果
执行9遍
done
[root@localhost ~]# vim xiangqi.sh
#!/bin/bash
#
#Compro
#打印国际象棋棋盘
i=1
定义变量值
while [ $i -le 8 ];do 判断循环,$i 小于等于8
j=1
while [ $j -le 8 ];do 判断循环,$j 小于等于8
sum=`expr $i + $j` 定义变量=运算 $i + $j
z=`expr $sum % 2` 上面结果的取模,取余, 每一行每一列进行相加1+1=2 %2=0 1+2=3
%2=1
[ $z -eq 0 ] && echo -ne "\033[41;1m
\033[0m"||echo -ne "\033[43;1m \033[0m" 变量z 小于等于0 就打印红色,
其它则打印黄色
let j++ 递增运算
循环
done
echo
let
i++ 递增运算 循环
done
until 循环
until codition;do
循环体
done
这种方式,跟while循环 恰恰相反,这个说的是当condition 条件成立时,就终止循环,
进入条件: codition 为 false
(假) 退出条件:condition 为 frue (真)
循环控制语句 continue ; break
用于循环体中
退出当此的循环
例如
#/bin/bash
i=1
unntil [ $i -gt 10 ];do 条件判断循环 变量i
是否大于 10
echo $i
let i++
在原有的值上面递增运算
[ $i -eq 5 ] && continue 条件判断,$i 是否等于5 ,
执行退出此次循环命令 ,而不是全部退出循环,只是退出匹配条件的循环
echo sss
显示sss分隔符。 当循环到5的时候停止。 在次从5开始又一次的循环
done
例如
#/bin/bash 打断,中断,停止此次循环。
i=1
unntil [ $i
-gt 10 ];do 条件判断循环 变量i 是否大于 10
echo $i
let
i++ 在原有的值上面递增运算
[ $i -eq 5 ] && break
条件判断,$i 是否等于5 ,当等于5的时候 ,停止退出此次循环。
echo sss 显示sss分隔符。
当循环到5的时候停止。
done
echo sss 这个不再循环体之内的字符, 是可以输出显示出来的。
[root@localhost
~]# vim
caicai.sh
#!/bin/bash
#
#user:Compro
#随机生成10以内的数字,实现猜数字游戏,提示提大会或者小,相等则退出
sj=$[$RANDOM%10+1]
定义变量名称=取模随机数10之内的
read -p "请输入数字:" sr 交互提示用户信息,
sr是下面准备用的变量
until [ $sj -eq $sr ];do 判断循环,$sj随机变量 等于
输入$sr变量, until条件成立时,就终止循环
#结果提示
[ $sr -lt $sj ] && echo
"x" 输入的小于随机 则提示小。
[ $sr -gt $sj ] && echo
"d" 输入的大于随机 则提示大。
read -p "请输入数字:" sr
只要是没输入跟随机相等的数字,则一直提示输入
done
echo "game over!"
当上面条件结束时 ,则提示游戏结束
运行脚本 [root@localhost ~]# bash caicai.sh
请输入数字:1 输入1
x 提示小
请输入数字:5
输入5
d 提示大
请输入数字:3 输入3
game
over! 游戏结束 证明脚本生成的随机数是3,相等则退出
原创文章,作者:小马哥,如若转载,请注明出处:http://www.178linux.com/37488