该系列文章只是本人的学习笔记,文章中的文字描述提取自《Linux鸟哥私房菜》《Linux运维之道》等书中的重点内容,化繁为简能够在工作中快速复习掌握重点,并不代表个人立场,但转载请加出处,并注明参考文献。

实际上Shell是一个命令解释器,它解释由用户输入的命令并且把它们送到内核,不仅如此,Shell有自己的编程语言用于对命令的编辑,它允许用户编写由shell命令组成的程序.Shel编程语言具有普通编程语言的很多特点,比如它也有循环结构和分支控制结构等,用这种编程语言编写的Shell程序与其他应用程序具有同样的效果,下面我们会介绍Shell-Script的编写.

Shell 条件判断

◆按文件类型判断◆

1.使用 [] 来执行判断,并使用echo $? 判断执行结果

[root@localhost ~]# ls
lyshark.log passwd.awk [root@localhost ~]# [ -e ./lyshark.log ]
[root@localhost ~]# echo $? #返回0表示文件 ./lyshark.log 存在
0 [root@localhost ~]# [ -e ./shar ] #返回1表示文件 ./shar 不存在
[root@localhost ~]# echo $?
1

2.我们可以结合之前所学的 && 和 || 实现判断后输出判断结果

[root@localhost ~]# ls
lyshark.log passwd.awk [root@localhost ~]# [ -e ./lyshark.log ] && echo "check ok" || echo "None"
check ok [root@localhost ~]# [ -e ./shar ] && echo "check on" || echo "None"
None

◆按文件权限判断◆

1.使用 -r 判断文件是否可读,和可执行

[root@localhost ~]# ls
lyshark.log passwd.awk [root@localhost ~]# [ -r ./lyshark.log ] && echo "check ok" || echo "None"
check ok [root@localhost ~]# [ -x ./lyshark.log ] && echo "check ok" || echo "None"
None [root@localhost ~]# [ -r ./lyshark.log ] && [ -x ./lyshark.log ] && echo "可读,可执行" || echo "可读,不可执行" || echo
"不可读,不可执行" 可读,不可执行

◆两文件之间的比较◆

1.通过 -ef 判断是否是相同的I节点

[root@localhost ~]# ls -li
total 0
8409155 -rw-r--r-- 2 root root 0 Sep 25 21:39 lyshark_ln.log
8409155 -rw-r--r-- 2 root root 0 Sep 25 21:39 lyshark.log [root@localhost ~]# [ ./lyshark.log -ef lyshark_ln.log ] && echo "ok" || echo "no"
ok

◆数值之间的比较◆

1.比较两数字,大小关系

[root@localhost ~]# [ 23 -ge 24 ] && echo "23 >= 24 " || echo "23 <= 24"
23 <= 24 [root@localhost ~]# [ 30 -ge 24 ] && echo "30 >= 24 " || echo "30 <= 24"
30 >= 24

◆字符串之间的比较◆

1.字符串之间的比较例子,字符串是否为空

[root@localhost ~]# name=LyShark
[root@localhost ~]# age=""
[root@localhost ~]# unset sex [root@localhost ~]# [ -z "$name" ] && echo "字符串空" || echo "不为空"
不为空 [root@localhost ~]# [ -z "$age" ] && echo "字符串空" || echo "不为空"
字符串空 [root@localhost ~]# [ -z "$sex" ] && echo "字符串空" || echo "不为空"
字符串空

2.两个字符串相等比较

[root@localhost ~]# x=100
[root@localhost ~]# y=200
[root@localhost ~]# z=100 [root@localhost ~]# [ "x" == "y" ] && echo "yes" || echo "no"
no
[root@localhost ~]# [ "$x" == "$y" ] && echo "yes" || echo "no"
no [root@localhost ~]# [ "$x" == "$z" ] && echo "yes" || echo "no"
yes

◆多重条件判断◆

1.逻辑与:判断变量x不为空,并且x大于20

[root@localhost ~]# declare -i x=10
[root@localhost ~]# [ -n "$x" -a "$x" -gt 20 ] && echo "yes" || echo "no"
no
[root@localhost ~]# declare -i x=30
[root@localhost ~]# [ -n "$x" -a "$x" -gt 20 ] && echo "yes" || echo "no"
yes

2.逻辑非:判断x变量不为空,或!取反

[root@localhost ~]# declare -i x=30

[root@localhost ~]# [ -n "$x" ] && echo "yes" || echo "no"
yes [root@localhost ~]# [ ! -n "$x" ] && echo "yes" || echo "no"
no

IF条件判断

if、then、else语句用于判断给定的条件是否满足,并根据测试条件的真假来选择相应的操作.if/else仅仅用于两分支判断,多分支的选择时需要用到if/else语句嵌套、if/elif/else和case多分支选择判断结构.

IF结构例子: 一个就简单的单分支结构.测试条件后如果没有";"则then语句要换行.

#!/bin/sh
echo "Please input a Number:"
read Num if [ "$Num" -lt 15 ]
then
echo "$Num <= 15"
fi

IF/IF-ELSE结构: 一个双分支结构,如下执行删除文件,成功返回then是否返回else.

#!/bin/sh

echo "Please input the file which you want to delete:"
read file if rm -f "$file"
then
echo "Delete the file $file sucessfully!"
else
echo "Delete the file $file failed!"
fi

IF/ELSE嵌套: 可同时判断三个或三个以上条件,但要注意if与else配对关系,else语句总是与它上面最近的未配对的if配对.

#!/bin/bash
#提示用户输入分数(0-100)
echo "Please Input a integer(0-100): "
read score #判断学生的分数类别
if [ "$score" -lt 0 -o "$score" -gt 100 ]
then
echo "The score what you input is not integer or the score is not in (0-100)."
else
if [ "$score" -ge 90 ]
then
echo "The grade is A!"
else
if [ "$score" -ge 80 ]
then
echo "The grade is B!"
else
if [ "$score" -ge 70 ]
then
echo "The grade is C!"
else
if [ "$score" -ge 60 ]
then
echo "The grade is D!"
else
echo "The grade is E!"
fi
fi
fi
fi
fi

IF/ELIF/ELSE结构: if/else嵌套在编程中很容易漏掉then或fi产生错误,而且可读性很差,因此引入if/elif/else结构针对某一事件的多种情况进行处理,fi只出现一次,可读性也提高了.

#!/bin/bash  

echo "Please Input a integer(0-100): "
read score if [ "$score" -lt 0 -o "$score" -gt 100 ]
then
echo "The score what you input is not integer or the score is not in (0-100)."
elif [ "$score" -ge 90 ]
then
echo "The grade is A!"
elif [ "$score" -ge 80 ]
then
echo "The grade is B!"
elif [ "$score" -ge 70 ]
then
echo "The grade is C!"
elif [ "$score" -ge 60 ]
then
echo "The grade is D!"
else
echo "The grade is E!"
fi

实例1: 通过单分支判断磁盘是否已满.

[root@localhost ~]# cat if.sh

#!/bin/bash

ret=$( df -h | grep "/dev/sda1" | awk '{printf $5}' | cut -d "%" -f 1 )
if [ $ret -ge 80 ]
then
echo -e "/dev/sda1 is full !!"
fi

实例2: 通过多分支判断磁盘是否已满.

[root@localhost ~]# cat if.sh
#!/bin/bash ret=$( df -h | grep "/dev/sda1" | awk '{printf $5}' | cut -d "%" -f 1 )
if [ $ret -ge 80 ]
then
echo -e "/dev/sda1 is full !"
else
echo -e "/dev/sda1 is not full !"
fi

实例3: 多分支判断小例子.

[root@localhost ~]# cat if.sh
#!/bin/bash read -p "输入一个数字:" num if [ "$num" -gt "100" ]
then
echo -e "这个数大于100"
elif [ "$num" -lt "100" ]
then
echo -e "这个数小于100"
elif [ "$num" -eq "100" ]
then
echo -e "这个数等于100"
fi

实例4: 判断输入的年份是否是润年(润年条件:1、能被4整除,但不能被100整除的年份.2、能被100整除,又能被400整除的年份)

#!/bin/sh

echo "Please Input a year: "
read year let "n1=$year % 4"
let "n2=$year % 100"
let "n3=$year % 400"
if [ "$n1" -ne 0 ]
then
leap=0
elif [ "$n2" -ne 0 ]
then
leap=1
elif [ "$n3" -ne 0 ]
then
leap=0
else
leap=1
fi

CASE分支结构

case结构变量值依次比较,遇到双分号则跳到esac后的语句执行,没有匹配则脚本将执行默认值*"后的命令,直到"';;"为止.case的匹配值必须是常量或正则表达式.

#!/bin/bash

read -p "输入一个符号:" temp

case $temp in

        "-print")
echo -e "您执行了print函数"
;;
"-save")
echo -e "您执行了save函数"
;;
"-help")
echo -e "您执行了help函数"
;;
*)
echo -e "您执行了其他操作"
;;
esac

FOR循环结构

Shell编程中循环命令用于特定条件下决定某些语句重复执行的控制方式,有三种常用的循环语句:for、while和until.while循环和for循环属于"当型循环",而until属于"直到型循环",循环控制符:break和continue控制流程转向.

列表FOR循环: 循环打印数据分别从1遍历到5.

do和done之间的命令称为循环体,执行次数和list列表中常数或字符串的个数相同.for循环,首先将in后list列表的第一个常数或字符串赋值给循环变量,然后执行循环体,以此执行list,最后执行done命令后的命令序列.

#!/bin/bash

for tmp in {1..5}
do
echo "Hello, Welcome $tmp times"
done

FOR循环累加: 通过FOR循环累加打印数据.

通过i的按步数2不断递增,计算sum值为2500.同样可以使用seq命令实现按2递增来计算1~100内的所有奇数之和,for i in $(seq 1 2 100),seq表示起始数为1,跳跃的步数为2,结束条件值为100.

#!/bin/bash
sum=0 for i in {1..100..2}
do
let "sum+=i"
done echo "sum=$sum"

FOR循环遍历目录: 通过for循环显示当前目录下所有的文件.

#!/bin/bash

for file in $( ls )
#for file in *
do
echo "file: $file"
done

不带列表FOR: 由用户制定参数和参数的个数,与上述的for循环列表参数功能相同.

#!/bin/bash

echo "number of arguments is $#"
echo "What you input is: " for argument
do
echo "$argument"
done

C风格FOR循环: 也被称为计次循环.

#!/bin/bash
for((integer = 1; integer <= 5; integer++))
do
echo "$integer"
done

实例1: 通过for循环打印1-10.

[root@localhost ~]# cat for.sh
#!/bin/bash for temp in `seq 1 10`
do
echo -e "打印数据: $temp"
done

实例2: 通过for循环计算1-100的累加和.

[root@localhost ~]# cat for.sh
#!/bin/bash declare -i sum=0 for temp in `seq 1 100`
do
sum=$sum+$temp
done echo -e "从1+到100的结果是: $sum"

实例3: 从列表中选择数据.

[root@localhost ~]# cat for.sh
#!/bin/bash for temp in 1 3 5 7 9
do
echo -e "打印: $temp"
done [root@localhost ~]# bash for.sh
打印: 1
打印: 3
打印: 5
打印: 7
打印: 9

实例4: 读取文件内容并打印.

[root@localhost ~]# cat for.sh
#!/bin/bash world=`cat /etc/passwd`
for temp in $world
do
echo -e "打印: $temp"
done

WHILE 循环

也称为前测试循环语句,重复次数是利用一个条件来控制是否继续重复执行这个语句.为了避免死循环,必须保证循环体中包含循环出口条件即表达式存在退出状态为非0的情况.

计数控制: 指定了循环的次数500,初始化计数器值为1,不断测试循环条件i是否小于等于100.在循环条件中设置了计数器加2来计算1~100内所有的奇数之和.

#!/bin/bash

sum=0

i=1

while(( i <= 100 ))
do
let "sum+=i"
let "i += 2"
done echo "sum=$sum"

结束标记控制的while循环: 设置一个特殊的数据值(结束标记)来结束while循环.

#!/bin/bash

echo "Please input the num(1-10) "
read num while [[ "$num" != 4 ]]
do
if [ "$num" -lt 4 ]
then
echo "Too small. Try again!"
read num
elif [ "$num" -gt 4 ]
then
echo "To high. Try again"
read num
else
exit 0
fi
done echo "Congratulation, you are right! "

标志控制的while循环: 使用用户输入的标志值来控制循环的结束(避免不知道循环结束标志的条件).

#!/bin/bash

echo "Please input the num "
read num sum=0
i=1 signal=0 while [[ "$signal" -ne 1 ]]
do
if [ "$i" -eq "$num" ]
then
let "signal=1"
let "sum+=i"
echo "1+2+...+$num=$sum"
else
let "sum=sum+i"
let "i++"
fi
done

命令行控制的while循环: 使用命令行来指定输出参数和参数个数,通常与shift结合使用,shift命令使位置变量下移一位($2代替$1、$3代替$2,并使$#变量递减),当最后一个参数显示给用户,$#会等于0,$*也等于空.

#!/bin/bash

echo "number of arguments is $#"
echo "What you input is: " while [[ "$*" != "" ]]
do
echo "$1"
shift
done

while计算: 通过while循环,计算1-100的累加和.

[root@localhost ~]# cat while.sh
#!/bin/bash declare -i x=0
declare -i num=0 while [ "$x" -lt "100" ]
do
x=$x+1
num=$num+$x
done echo -e "从1-100结果是: $num" [root@localhost ~]# bash while.sh
从1-100结果是: 5050

UNTIL 循环

until命令和while命令类似,while能实现的脚本until同样也可以实现,但区别是until循环的退出状态是不为0,退出状态是为0(与while刚好相反),即whie循环在条件为真时继续执行循环而until则在条件为假时执行循环.

#!/bin/bash

i=0

until [[ "$i" -gt 5 ]]    #大于5
do
let "square=i*i"
echo "$i * $i = $square"
let "i++"
done
#!/bin/bash

for (( i = 1; i <=9; i++ ))
do for (( j=1; j <= i; j++ ))
do
let "temp = i * j"
echo -n "$i*$j=$temp "
done echo "" #output newline
done
#!/bin/bash

i=0

until [[ "$i" -gt 5 ]]    #大于5

do

    let "square=i*i"

    echo "$i * $i = $square"

    let "i++"

done

跳出语句(break,continue)

break: 在for、while和until循环中break可强行退出循环,break语句仅能退出当前的循环,如果是两层循环嵌套,则需要在外层循环中使用break.

#!/bin/bash

sum=0
for (( i=1; i <= 100; i++))
do
let "sum+=i" if [ "$sum" -gt 1000 ]
then
echo "1+2+...+$i=$sum"
break
fi
done

continue: 在for、while和until中用于让脚本跳过其后面的语句,执行下一次循环.continue用于显示100内能被7整除的数.

#!/bin/bash

m=1
for (( i=1; i < 100; i++ ))
do
let "temp1=i%7" #被7整除 if [ "$temp1" -ne 0 ]
then
continue
fi echo -n "$i " let "temp2=m%7" #7个数字换一行 if [ "$temp2" -eq 0 ]
then
echo ""
fi let "m++"
done

SELECT 语句

select结构从技术角度看不能算是循环结构,只是相似而已,它是bash的扩展结构用于交互式菜单显示,功能类似于case结构比case的交互性要好.

[root@localhost ~]# cat select.sh
#!/bin/bash echo -e "请选择系统类型?" select var in "Linux" "GNU HURD" "FreeBSD" "Other";
do
if [ $var == "Linux" ]
then
echo -e "您的系统是Linux"
elif [ $var == "FreeBSD" ]
then
echo -e "您的系统是FreeBSD"
fi
break
done
[root@localhost ~]# bash select.sh
请选择系统类型?
1) Linux
2) GNU HURD
3) FreeBSD
4) Other #? 1
您的系统是Linux
#!/bin/bash

declare -a serial
serial=(1 2 3 4)
PS3="Enter a number: " select var in "a" "b" "c" "d"
do
if ! echo ${serial[@]} | grep -q $REPLY
then
echo "please enter [1-4]."
continue
fi echo "your anwser is: $var"
break
done [root@localhost ~]# bash select.sh
1) a
2) b
3) c
4) d
Enter a number: 1
your anwser is: a

FUNCTION 函数

[root@localhost ~]# cat function.sh
#!/bin/bash function my_print()
{
echo -e "------------------------"
echo -e "hello world"
echo -e "------------------------"
return "127"
} my_print
echo $? [root@localhost ~]# bash function.sh
------------------------
hello world
------------------------
127

参考文献:Linux鸟哥私房菜,Linux运维之道

Linux Shell脚本编程提高(12)的更多相关文章

  1. Linux shell脚本编程(一)

    Linux shell脚本编程: 守护进程,服务进程:启动?开机时自动启动: 交互式进程:shell应用程序 广义:GUI,CLI GUI: CLI: 词法分析:命令,选项,参数 内建命令: 外部命令 ...

  2. Linux shell脚本编程(三)

    Linux shell脚本编程 流程控制: 循环语句:for,while,until while循环: while CONDITION; do 循环体 done 进入条件:当CONDITION为“真” ...

  3. Linux shell脚本编程(二)

    Linux shell脚本编程(二) 练习:求100以内所有偶数之和; 使用至少三种方法实现; 示例1: #!/bin/bash # declare -i sum=0 #声明一个变量求和,初始值为0 ...

  4. Linux Shell脚本编程--Linux特殊符号大全

    Linux Shell脚本编程--Linux特殊符号大全 linux_shell 特殊符号的介绍 2011

  5. Linux Shell脚本编程while语句

    Linux Shell脚本编程while语句案例 1,每隔3秒,打印一次系统负载 #!/bin/bash while truedo    uptime    sleep 3done 2,把监控结果保存 ...

  6. Linux shell脚本编程基础之练习篇

    shell脚本编程基础之练习篇. 1.编写一个脚本使我们在写一个脚本时自动生成”#!/bin/bash”这一行和注释信息. #!/bin/bash ] then echo "请输入一个参数& ...

  7. Linux Shell脚本编程-基础1

    概述:  shell脚本在Linux系统管理员的运维工作中非常重要.shell脚本能够帮助我们很方便的管理服务器,因为我们可以指定一个任务计划,定时的去执行某一个脚本以满足我们的需求.本篇将从编程基础 ...

  8. 【学习】Linux Shell脚本编程

    1.脚本的组成和执行 Linux shell脚本的结构并不复杂,其主要由变量.内部命令以及shell的语法结构和一些函数.其他命令行的程序等组成,以下是一个简单的shell脚本. #!/bin/bas ...

  9. [linux] shell脚本编程-xunsearch安装脚本学习

    安装脚本setup.sh #!/bin/sh # FULL fast install/upgrade script # See help message via `--help' # $Id$ # s ...

随机推荐

  1. web.xml 详细介绍(zz)

    web.xml 详细介绍 博客分类: CoreJava WebXMLServletJSPTomcat  http://mianhuaman.iteye.com/blog/1105522 1.启动一个W ...

  2. hdu 5120 (求两圆相交的面积

    题意:告诉你两个圆环,求圆环相交的面积. /* gyt Live up to every day */ #include<cstdio> #include<cmath> #in ...

  3. kbmmw 中简单返回 extjs 数据JSON

    以前,我们通过自己写json 来返回数据表的内容.在delphi 10.2.2中,官方自带了一个FDBatchMoveJSONWriter1 来直接处理数据库内容.把结果推送到浏览器客户端. 今天我们 ...

  4. Codeforces gym 102062 简要题解

    文章目录 A. Bob and BoB B. Vibranium Gift C. The Blood Moon D. Palindrome and Chocolate E. Jumpy Robot F ...

  5. 2018.11.01 NOIP训练 cost数(搜索+容斥原理)

    传送门 唉考试的时候忘记剪倍数的枝了666666分滚粗. 其实就是一直取lcmlcmlcm搜索,然后容斥原理统计就行了. 代码

  6. 假期训练五(poj-1077bfs+康拓展开,hdu-2577dp)

    题目一:传送门 思路:主要是找到状态, 考虑字母有两种状态,大写和小写, 从小写变为大写的变化方式有两种:保持cap状态,或者按住shift键: 从小写变为大写也有一种变化方式:按住shift键: 看 ...

  7. windows、linux下通过ftp上传文件小脚本

    一.windows @echo off #open ip 将要上传文件的IP地址echo open IP>ftp.up #用户名echo ninic>>ftp.up #密码echo ...

  8. c++关键字volatile的作用

    1.易变性 1.1概念 编译器对volatile修饰的变量,当要读取这个变量时,任何情况下都会从内存中读取,而不会从寄存器缓存中读取(因为每次都从内存中读取体现出变量的“易变”) 1.2测试代码(VS ...

  9. IntelliJ IDEA 2017版 SpringBoot测试类编写

    SpringBoot的测试类编写Demo 源码见 https://github.com/liushaoye/baseone.git

  10. js判断软键盘是否开启弹出

    移动端关于页面布局,如果底部有position:fixed的盒子,又有input,当软键盘弹出收起都会影响页面布局.这时候Android可以监听resize事件,代码如下,而ios没有相关事件. va ...