分享

shell编程系列一文读懂shell编程:总结了shell编程中常见的内容

hyj 2020-2-2 15:45:01 发表于 知识型 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 2 2360
问题导读
1.shell执行方法有哪些?
2.shell中变量都有哪些?
3.shell逻辑判断语法有什么特点?

shell对于我们传统程序来说,还是不太熟悉的。对于工作中,我们掌握一些shell的内容,可以让我们的程序更快,编程更方便。同时shell亦是面试要求中比较常见的技能要求。


此篇文章如果都完全整我,可以让我们阅读、学习大部分shell程序。

shell脚本结构和执行方法
1.shell脚本开头需要加#!/bin/bash
2.以#开头的行作为注释
3.脚本的名字以.sh结尾,用于区分这是一个shell脚本
4.执行方法有两种:
1)bash test.sh
2)./test.sh
#第二种执行方式需要有执行权限(chmod +x test.sh)
5.查看脚本执行过程:bash -x test.sh
6.查看脚本是否语法错误:bash -n test.sh

#bash可以使用sh命令代替(在/usr/bin目录下,sh是bash的软连接文件)

date命令的用法

对于date命令,获取年月日,一般使用+号连接;%用来自定年月日,具体指定都是使用英文首写字母来表示。比如年用%Y,月 +%m,如%y。
具体内容如下:
[mw_shl_code=bash,true][root@linux ~]# date
2019年 11月 19日 星期二 16:20:04 CST
[root@linux ~]# date +%Y-%m-%d
2019-11-19
[root@linux ~]# date +%Y
2019
[root@linux ~]# date +%m
11
[root@linux ~]# date +%d
19
[root@linux ~]# date +%y        #表示2019年,忽略20
19
[root@linux ~]# date +%F
2019-11-19
[/mw_shl_code]

对于日期的计算,比如三天后,三天前则使用减号来连接,对于三天前,和三天后,分别如下表示:
[mw_shl_code=bash,true][root@linux ~]# date
2019年 11月 19日 星期二 16:34:37 CST

[root@linux ~]# date -d "+3day"                        #三天后
2019年 11月 22日 星期五 16:34:45 CST

[root@linux ~]# date -d "-3day" +%F                #三天前
2019-11-16

[root@linux ~]# date -d "-3 month" +%F                #三个月前
2019-08-19

[root@linux ~]# date -d "-30 min" +%F_%T        #30分钟前
2019-11-19_16:06:16
[/mw_shl_code]

shell中变量的用法
shell中的变量什么时候使用?
1.当脚本中使用某个字符串较频繁并且字符串长度很长时就应该使用变量代替

2.使用条件语句时,常使用变量判断大小 if [ $a -gt 1 ]; then … ; fi
3.引用某个命令的结果时,用变量替代 n=wc -l test.txt

4.写和用户交互的脚本时,变量也是必不可少的 :
[mw_shl_code=bash,true][root@linux ~]# read -p "input a number:" n
input a number:15
[root@linux ~]# echo $n
15
[/mw_shl_code]


如果没有自定义变量,可以使用内置变量$REPLY:
[mw_shl_code=bash,true][root@linux ~]# read -p "input a number:"
input a number:9
[root@linux ~]# echo $REPLY
9
[/mw_shl_code]

上面未默认的$REPLY,除了还有内置变量。

5.$1,$2,$3,$# ($1 第一个参数,$2 第二个参数,$#表示参数的和):
如果我们有编程经验,变量可能我们还是认识的,内置变量,可能会难住我们,不知道它是什么意思。因此这里可以让我们对shell编程更加的熟悉。


$1,$2,$3,$# ($1 第一个参数,$2 第二个参数,$#表示参数的和):
[mw_shl_code=bash,true]#!/bin/bash
echo "第一个参数是$1"
echo "第二个参数是$2"
echo "一共有$#个参数"
[/mw_shl_code]

结果示例:
[mw_shl_code=bash,true][root@linux ~]# ./test.sh a b c
第一个参数是a
第二个参数是b
一共有3个参数
[/mw_shl_code]

$0表示脚本名(根据执行脚本方式的不同结果不同):
[mw_shl_code=bash,true]#!/bin/bash
echo "\$0是:$0"
[/mw_shl_code]

[mw_shl_code=bash,true][root@linux ~]# /root/test.sh
$0是:/root/test.sh
[root@linux ~]# ./test.sh
$0是:./test.sh
[root@linux ~]# sh test.sh
$0是:test.sh
[/mw_shl_code]
6.数学运算a=1;b=2; c=$(($a+$b))或者$[$a+$b]:
[mw_shl_code=bash,true][root@linux ~]# a=1
[root@linux ~]# b=2

[root@linux ~]# c=$(($a+$b))
[root@linux ~]# echo $c
3
[root@linux ~]# d=$[$a+$b]
[root@linux ~]# echo $d
3
[/mw_shl_code]


shell逻辑判断语法
既然为编程,我们知道任何语言都是需要有逻辑判断的,比如if else,while,for等这是最基本的组成部分,这里shell同样也是的。
格式1:if 条件 ; then 语句; fi
[mw_shl_code=bash,true]#!/bin/bash
read -p "input a number:" n
if [ $n -gt 5 ]
then
    echo "1"
fi
[/mw_shl_code]


格式2:if 条件; then 语句; else 语句; fi
[mw_shl_code=bash,true]#!/bin/bash
read -p "input a number:" n
if [ $n -gt 5 ]
then
    echo "1"
else
    echo "2"
fi
[/mw_shl_code]

格式3:if …; then … ;elif …; then …; else …; fi
[mw_shl_code=bash,true]#!/bin/bash
read -p "input a number:" n
if [ $n -gt 90 ]
then
    echo "A"
elif [ $n -gt 70 ]
then
    echo "B"
else
    echo "C"
fi
[/mw_shl_code]

格式4:if 中嵌套 if
[mw_shl_code=bash,true]#!/bin/bash
read -p "input a number:" n
if [ $n -gt 70 ]
then
    echo "OK"
    if [ $n -gt 90 ]
    then
         echo "A"
    elif [ $n -gt 80 ]
    then
         echo "B"
    else
         echo "C"
    fi
else
    echo "???"
fi
[/mw_shl_code]

上面我们看到其实跟其他编程是差不多的,唯一的不同是多了一个fi。

shell比较符
-gt 大于(>)
-lt 小于 (<)
-ge 大于等于 (>=)
-le 小于等于 (<=)
-eq 等于 (==)
-ne 不等于 (!=)

可以使用 && || 结合多个条件

大于5并且小于10:

[mw_shl_code=bash,true]if [ $a -gt 5 ] && [ $a -lt 10 ]; then
[/mw_shl_code]
第二种写法:
[mw_shl_code=bash,true]if [ $a -gt 5 -a $a -lt 10 ]; then
[/mw_shl_code]

#-a表示:and

大于5或小于3:

[mw_shl_code=bash,true]if [ $b -gt 5 ] || [ $b -lt 3 ]; then
[/mw_shl_code]

第二种写法:
[mw_shl_code=bash,true]if [ $b -gt 5 -o $b -lt 3 ]; then
[/mw_shl_code]


#-o表示or


if判断文件或目录的属性
[ -f file ] 判断是否是普通文件,且存在
[ -d file ] 判断是否是目录,且存在
[ -e file ] 判断文件或目录是否存在
[ -r file ] 判断文件是否可读
[ -w file ] 判断文件是否可写
[ -x file ] 判断文件是否可执行

补充:
1.如果判断对象为socket等特殊文件,可以使用-e判断是否存在

2.root用户对文件的读写比较特殊,即使一个文件没有给root用户读或者写的权限,root用户照样可以读或者写(x:执行权限除外)

3.取反使用感叹号:


补充:
1.如果判断对象为socket等特殊文件,可以使用-e判断是否存在

2.root用户对文件的读写比较特殊,即使一个文件没有给root用户读或者写的权限,root用户照样可以读或者写(x:执行权限除外)

3.取反使用感叹号:

[mw_shl_code=bash,true]if [ ! -f filename ]
[/mw_shl_code]

if判断的一些特殊用法
判断变量为空时:

[mw_shl_code=bash,true]if [ -z "$a" ]; then ...
[/mw_shl_code]

判断变量不为空时:
[mw_shl_code=bash,true]if [ -n "$a" ]; then ...
[/mw_shl_code]

判断命令成功时:
[mw_shl_code=bash,true]if ls /tmp/test.sh; then ...
[/mw_shl_code]

#判断文件是否存在的用法,当ls命令执行成功时,要怎样…

将产生的信息重定向到/dev/null:

[mw_shl_code=bash,true]if ls /tmp/test.sh &> /dev/null; then ...
[/mw_shl_code]
#不管ls命令执行是否成功,都将输出的信息流写入到/dev/null,不打印

判断文件是否包含关键字:

[mw_shl_code=bash,true]if grep -q '123' /tmp/test.sh; then ...
[/mw_shl_code]
#当文件包含关键字时,要怎样…,-q:包含关键字时,不输出匹配到的信息

if [ $a -gt 5 ]的另一种写法:

[mw_shl_code=bash,true]if (($a>5)); then ...
[/mw_shl_code]
#[ ] 中不能使用<,>,==,!=,>=,<=这样的符号,但双括号中可以


shell中case判断用法

[mw_shl_code=bash,true]case  变量名 in
   value1)   
        command  
            ;;
   value2)      
        command  
        ;;
   *)  
        commond
        ;;     
     esac

在case中,可以在条件中使用|,表示或的意思:
    2|3)     
            command
            ;;
[/mw_shl_code]

示例:
[mw_shl_code=bash,true]#!/bin/bash
read -p "input a number: " n
#判断输入内容是否为空
if [ -z "$n" ]
then
    echo "Please input a number."
    exit 1
fi
#判断输入内容是否含有非数字
n1=`echo $n|sed 's/[0-9]//g'`
if [ -n "$n1" ]
then
echo "Please input a number."
exit 1
fi
#当输入内容非空且为纯数字时,开始判断
if [ $n -lt 60 ] && [ $n -ge 0 ]
then
    t=1
elif [ $n -ge 60 ] && [ $n -lt 80 ]
then
    t=2
elif [ $n -ge 80 ]  && [ $n -lt 90 ]
then
    t=3
elif [ $n -ge 90 ] && [ $n -le 100 ]
then
    t=4
else
    t=0
fi

case $t in
    1)
                echo "D"
        ;;
    2)
        echo "C"
        ;;
    3)
        echo "B"
        ;;
    4)
        echo "A"
        ;;
    *)
        echo "The number range must be 0-100."
        ;;
esac
[/mw_shl_code]


for、while循环
for循环语法:for 变量名 in 条件; do …; done

示例一:打印1-100的数字并求和

[mw_shl_code=bash,true]#!/bin/bash
sum=0
for i in `seq 1 100`
do
        sum=$[$sum+$i]
        echo $i
done
echo $sum
[/mw_shl_code]
seq1 2 10:打印结果1,3,5,7,9(2表示步长,打印结果间隔为2)
seq10 -2 1:打印结果10,8,6,4,2(倒序打印步长为负)
seq -w 1 10:打印结果01,02,03,04,05,06,07,08,09,10(-w 表示等宽)

示例二:打印指定目录下的文件
[mw_shl_code=bash,true]#!/bin/bash
cd /etc
for i in `ls /etc`
do
        if [ -f $i ]
        then
                ls -l $i
        fi
done
[/mw_shl_code]


while循环语法:while 条件; do … ; done

示例一:平均1分钟负载大于5时,发送邮件

[mw_shl_code=bash,true]#!/bin/bash
while :
do
        load=`w|head -1|awk -F 'load average: ' '{print $2}'|cut -d . -f1`
        if [ $load -gt 5 ]
        then
                d=`date +%F_%T`
                top -nb1|mail -s "$d load is high: $load" asnfy@qq.com
        fi
        sleep 30
done
[/mw_shl_code]
示例二:判断输入内容是否为空或包含非数字
[mw_shl_code=bash,true]#!/bin/bash
while :
do
    read -p "Please input a number: " n
    if [ -z "$n" ]
    then
                echo "you need input sth."
                continue
    fi
    n1=`echo $n|sed 's/[0-9]//g'`
    if [ -n "$n1" ]
    then
                echo "you just only input numbers."
        continue
    fi
    break
done
echo "you input number is $n"
[/mw_shl_code]

#如果输入的内容为空为包含非数字,continue跳出重新执行,否则break结束循环

补充:
当使用for遍历一个文件中的每行内容时(for i in `cat test`),如果某行中有一个或多个空格,这行的内容就会被当做两行或多行打印,为了避免这种情况可以使用while来循环输出文件中的每行内容
示例:
[mw_shl_code=bash,true]#!/bin/bash
cat test.txt|while read i
do
        echo $i
done
[/mw_shl_code]

#使用while遍历文件中的内容,即使某行有空格,也会被正常打印


break、continue、exit
break:直接结束循环

[mw_shl_code=bash,true]#!/bin/bash
for i in `seq 1 5`
do
        echo "第一次输出:$i"
        if(($i==3))
        then
                break
        fi
        echo "第二次输出:$i"
done
echo "循环结束"
[/mw_shl_code]
执行结果:
[mw_shl_code=bash,true][root@linux ~]# sh a.sh
第一次输出:1
第二次输出:1
第一次输出:2
第二次输出:2
第一次输出:3
循环结束
[/mw_shl_code]

continue:忽略后面的代码,从新开始循环
[mw_shl_code=bash,true]#!/bin/bash
for i in `seq 1 5`
do
        echo "第一次输出:$i"
        if(($i==3))
        then
                continue
        fi
        echo "第二次输出:$i"
done
echo "循环结束"
[/mw_shl_code]

执行结果:
[mw_shl_code=bash,true][root@linux ~]# sh a.sh
第一次输出:1
第二次输出:1
第一次输出:2
第二次输出:2
第一次输出:3
第一次输出:4
第二次输出:4
第一次输出:5
第二次输出:5
循环结束
[/mw_shl_code]

注意:循环支持嵌套,如果一个循环中嵌套了多个循环,break或continue只能作用于所在的某个循环中

exit:直接退出脚本

[mw_shl_code=bash,true]#!/bin/bash
for i in `seq 1 5`
do
        echo "第一次输出:$i"
        if(($i==3))
        then
                exit        
        fi
        echo "第二次输出:$i"
done
echo "循环结束"
[/mw_shl_code]

执行结果:
[mw_shl_code=bash,true][root@linux ~]# sh a.sh
第一次输出:1
第二次输出:1
第一次输出:2
第二次输出:2
第一次输出:3
[/mw_shl_code]

#循环外的echo语句没有输出,当脚本中遇到exit,会直接退出,后面所有内容都不再执行

补充:
当脚本遇到exit直接退出后,echo $? 查看执行结果会显示0,表示执行成功,所以一般使用exit会在后面加上指定的非0数字,方便调用结果(比如:exit 5)



加微信w3aboutyun,获取更多资源



领取100本书+1T资源
http://www.aboutyun.com/forum.php?mod=viewthread&tid=26480

大数据5个项目视频
http://www.aboutyun.com/forum.php?mod=viewthread&tid=25235

名企资源、名企面试题、最新BAT面试题、专题面试题等资源汇总
https://www.aboutyun.com/forum.php?mod=viewthread&tid=27732




参考:
https://blog.csdn.net/Powerful_Fy/article/details/103145114




已有(2)人评论

跳转到指定楼层
YTP520YTP 发表于 2020-2-3 10:45:12
shell 编程学习
回复

使用道具 举报

YTP520YTP 发表于 2020-3-5 17:45:53
66666666666不错
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条