BASH编写入门与实例

怎么写shell脚本:
。使用任何编辑工具编写shell脚本 例如vi
    -#!/bin/bash    #在第一行放置头格式说明
  -#!/usr/bin/gawk  //awk需要添加的头格式,让系统知道用什么方式去解析此文件
  -#!/usr/local/bin/python    //python的头格式
。在写完shell脚本之后,设置脚本执行权限 -chmod +x you-script-name -chmod 755 your-script-name 。执行你的脚本做测试 -bash your-script-name -sh your-script-name -./your-script-name
shell中的变量
。Linux(shell)中有两种类型的变量:
    -系统变量:由Linux系统本身维护,通常为大写的变量名
    -用户定义变量(UDV):由用户创建和维护,通常小写
。查看系统变量可以通过Linux指令set罗列出来,也可以输入declare
。在调用变量时,在名称前加以“$"(美元符号)
    -echo $USERNAME
    -echo $HOME
如何定义用户自己的变量
。要定义UDV可以使用下面的语法:
    变量名=值    (注意:等号之间没有空格)
。通过”=“将右边的值赋给左边的变量
    no=10    #正确
    10=no    #错误,值必须在右边
    vech=Bus    #顶一个一个vech的变量值为Bus
    n= 30    #错误,等号右边存在空格
    n =20    #错误,等号左边存在空格
。只读变量设置:
#readonly BOOK=”Linux“
#BOOK=”Windows“  //将会报错。
取消变量#unset BOOK
彩色Shell输出
。echo -e 指令可以在控制台输出彩色的字符。
。色彩分为前景色和背景色,十位数的数字3或4表示
    -前景色30-37(以3x代表)
    -背景色40-47(以4x代表)
。个位数表示为色彩
    30(黑色)、31(红色)、32(绿色)、33(黄色)、34(蓝色)、35(洋红)、36(青色)、37(白色)。
。前景色和背景色个位数不要一致,否则看不到任何信息(可以用在密码输入处)
彩色Shell输出二
。使用格式:
    -    \033[前景色;背景色m    #同事更改前/背景色
    -    \033[前景色m    #只更改前景色
    -    \033[背景色m    #只更改背景色
    -    \033[0m    #还原所有的前/背景色,最后部分一定要还原色彩
。echo "You are login to \033[34;40m bulefox \033[0m system"  //这里的第一个\033[[34;40m是说前景色和背景色设置,而\033则是让所有的前景色和背景色还原。
    -打印蓝色的bulefox
。下面的代码用在防止密码被窥探
    echo "Please input a password”
   echo -e “\033[34;44m" read PASSWD;
   echo -e "\033[0m" echo PASSWD | openssl md5
echo命令
。使用echo 命令可以显示文本或比变量的值
。echo 【选项】【字符,变量...】
。选项
    -n 不换行输出,默认echo一次换一行,用在持续的打印输出
    -e启用转义字符解析
        \a    响铃    \b    退格    \c去除尾部的新行
        \n    新的一行    \r    回车    \t    水平制表符功能
        \\    斜杠
    echo -e "An apple a day keeps away \a\t\tdoctor\n"
shell中数学计算
。使用下面的语法执行数学运算,注意中间都存在空格,一次只能处理两个数字
    语法:expr    操作数1    数学计算    操作数2
    expr 1+3    #加法计算
    expr 10/2    除法计算
    expr 20%3    求余数
    expr 10\*3    #乘法他叔,由于”*“星号为通配符之一,必须对*转义
    echo ‘expr 6+3‘    #显示结果,注意”‘"(斜点)的使用,代表先行执行Bash命令
。如果使用echo “expr 6+3”或者echo 'expr 6+3'将显示“expr 6+3”字符本身
将表达式计算结果赋值给变量方法:
#TMP=$(expr 3333 \*10)  //将3333*10的结果赋值给变量TMP
#echo “$((1+100/3*6))"  // 可以使用括号的方式进行运算,这种限制比较少

引号的使用
。我们来区分一下引号
    ”“(双引号)    对”\"做转义,对“$"的变量做解析
    ''(单引号)    其中的内容不作任何修改
    ‘‘(斜点)    用来执行命令
。请观察下面的命令区别:
    -echo ”Today is date“    #输出Today is date
    -echo ”Today is ‘date‘“    #输出Today is 及日期
    -echo 'Today is ‘date‘’    #原样输出Today is ‘date‘ 
退出和退出状态
。在Linux执行指令,它将返回两种类型的值,用来判断此前执行的命令或shell脚本成功与否
    -返回0,命令执行成功
    -返回任何不为0,命令不成功或者执行中有一些错误
。这些值称呼为退出状态,可以通过$?检查退出状态
    -rm nonexist-file
    -echo $?
    -ls
    -echo $?  //判断前面一条指令执行成功与否,立刻执行echo $?查看返回值,0表示执行成功,否则执行失败。
通配符的使用
。”*“星号代表任何的字符出现0到多次
    ls /lib/*.so    //任何以.so为后缀的文件
    ls /lib/lib*.so.*    //以lib开头+.so.+任何其他后缀
。”?“问号代表一个而且只有一个任何字符
    ls /lib/lib??.so.?    //此文件名长度为10
。”[]“括号内提供的字符选择一个
    ls /lib/lib[bcp]*.so     //b,c,p选一,libb,libc,libp
。”[-]“括号内一段字符,0-9数字,a-z小写,A-Z大写
    ls /lib/lib[b-p]*.so    //从b到p选择一个
  ls /lib/lib[a-z]*.so等同于ls /lib/lib[ab-z]*.so 。”[^]"括号内的都排除掉,[^bc]除了b和c以外的其他全部 ls /lib/lib[^c]*.so.*
命令行的处理
。Linux绝大多数命令可以带参数和选项,请识别下面的命令带有多少参数
#命令                #参数总数($#)
ls foo                #1
cp y y.bak            #2
date                     #0
tail -10 myf            #2
mail raj                #1
sort -r -r myf        #2
命令行参数
。根据前面观察的结果
    -$#保存着命令后面所带的参数的总数
    -$*或者$@将命令后的所有参数作为一个字符串保存
  -$0  永远是命令本身
  -$1,2,3...  命令参数

 

  

shell脚本中条件判断
。返回shell中0(代表True)或1(False)结果
    -if/then结构
    -test或者[...]执行shell测试,返回shell结果
。Bash2.02版本以上[[...]]
。返回常规编程语言格式的结果
    -((...))和let...还可以做数字的比较
。bc指令提供我们对条件的测试
测试条件:
。字符比较        数字比较        代表意思
    ==                -eq            相等
    >                   -gt            大于
    <                   -lt             小于
    !=                  -ne            不等于
    <=/>=           -le/ge        小于等于/大于等于
多个条件测试时
    -a并且,逻辑与-o或者,逻辑或
test命令或[]
。[]中写入测试条件,注意条件和开/闭中括号之间要保留空格
。初学者使用此模式时,要特别注意,0代表TRUE,可以理解成没有错误,而1代表FALSE
    if [ 0 ];then
        echo "0 is true"
    else
        echo "0 is false"
    fi
if...else...fi
。语法:
    if [ 条件判断]
    then
        命令1        #上面条件判断结果为0,代表TRUE
        命令2
    else
        命令3        #上面条件判断结果为1,代表FALSE
        命令4
    fi
if语句直接使用示例
。if语句可以直接使用Shell指令,再根据$?结果判断
    DIR=/var/test
    if cd $DIR &> /dev/null;then    #直接丢弃错误消息,这里由于不需要判断条件,这里的条件就可以去掉[]
        echo "now in $DIR"
    else
        echo "Can't change to $DIR"
    fi
测试文件/文件夹属性
。常见判断
    -a    #文件是否存在
    -b    #文件是否为块设备
    -d    #文件是否为目录
    -s    #文件大小是否为0
    -r    #文件是否具有可读权限
    -w    #文件是否具有可写权限
    -x    #文件是否具有可执行权限
。man bash可以得到更为详尽的帮助
#[ -f /etc/passwd ]; echo $?  //查看/etc/passwd文件是否存在
if语句嵌套
。一步一步测试时,可能需要if-then-else语句的嵌套使用
OSCH=0
echo “1.Unix(IBM AIX)”
echo “2.Linux(Red Hat Enterprise Linux)”
read OSCH
if [ $OSCH -eq 1 ]; then
    echo "You pick UNIX OS"
else
    if [ $OSCH -eq 2 ];then
        echo "Your Pick Linux OS"
    else
        echo "What you don't Like Linux/Unix OS"
    fi
fi
多级if-then-else
。多级if-then-else可以替换掉if-then-else的嵌套使用,直接使用另一个/多个条件测试,请将之前的程序修改以下语法
。语法
if    [    测试条件1    ];then
    命令1
elif  [    测试条件2    ];then
    命令2
elif    [    测试条件n    ];then
    命令n
else
    命令
fi
退出和退出状态
。在Linux执行指令,它将返回两种类型的值,用来判断此前执行的命令或shell脚本成功与否
    -返回0,命令成功
    -返回任何不为0,命令不成功或者在执行中有一些错误
。这些值称呼为退出状态,可以通过$?检查退出状态
    -rm    nonexit-file
    -echo    $?
    -ls
    -echo    $?
case语句
。case语句是多级if-then-elif语句的替代语句。可以让你多个值做匹配测试,更方便读写。
。语法:
case 变量名    in
    匹配1)    命令1;;
    匹配2)    命令2;;
    匹配N)    命令N;;
    *)    命令;;
esac
比较以下两段代码:、

 

 

 

将手动写的脚本加入到chkconfig里面步骤:
比如已经编写好的myserv.sh脚本,需要加入到开机启动里面
1.将此脚本加入到/etc/init.d
#mv myserv.sh /etc/init.d/myserv
2.需要在脚本中添加chkconfig和descirption信息,可以参考/etc/init.d/network部分,下图中标色部分即为需要添加内容
3.chkconfig --add myserv  //添加此服务到chkcofnig下
4.chkcofnig --list myserv  //查看该服务在不同级别下启停状态。

 

 

Shell中loop循环
循环的定义:
    -计算机可以重复一而再,再而三的执行特定的指令,直到给定的条件满足为止,重复执行的这一组指令就叫做loop
。Bash中支持
    -for loop    
    -while loop
。注意每个循环使用时
    首先,用在循环中的变量必须要在循环前初始化
    对每次循环都需要对条件做测试
    在循环体中执行一次需要对循环测试条件值修改  
for loop
。语法:
        for    变量名    in    列表
        do    
                循环体
        done
。列表就是一个集合,集合由空格间隔,可以使以下的集中:
    -数字/字符集合
        -1 2 5 7 9
        -{1...254}
    -文件集合
        -/etc/*.conf
    -指令结果集合
        -$(find /etc/ -perm -003)
实例1(数字循环):
创建file1,2,3,4文件
#touch file{1,2,3,4,5}
#vim test.sh
内容如下:
#!/bin/bash
for FILENAME in file1 file2  file3 file5
do
    echo "You are going to remove the $FILENAME
    rm $FILENAME -f 
done

实例2:
。数字集合
#vim test.sh
内容如下:
#!/bin/bash
echo "#!/bin/bash" > /bin/setFilewall.sh
for IP in {1...254}
do
    echo "iptables -I INPUT -s 192.168.0.$IP -p tcp
        -m state --state NEW -j ACCEPT" >>
        /bin/setFirewall.sh
done
/etc/sysconfig/selinx    //其中/etc/sysconfig通过dirname可以获取,而selinux则可以通过basename获取。
#date +%F  //可以获取当前日期

for loop实例三
for FILE in $(find /var/ -size +10M)
do
    rm -f $FILE 
    logger "$FILE has been deleted"
    echo -e "\033[33m$FILE\033[0mhas been deleted">>/var/tmp/largefile.log
done
获取某个文件中的空格或者换行的ip地址方法:
#cat /etc/testservers.conf | grep -Ev '^(#|$)'
如获取以下文件中的有效ip
#vim testservers.conf
文件内容如下:
#This file is the host ip
#172.23.2.1
192.168.1.1
#FTP Server
192.13.1.1
127.0.0.1
        192.156.1.1
全文搜索实例:
此脚本用于搜多某个目录下所有文件里面是否含有某个关键字
脚本内容如下:
#!/bin/bash DIR=$1 KEYWORD=$2 for FILENAME in $(find $DIE -type f) do if grep $KEYWORD $FILENAME &> /dev/null;then echo "The file -->$FILENAME has the keyword" #else fi done
for loop循环嵌套一

for NUM1 in {1. .9}
do
    for NUM2 in {1..9}
    do
        RES = $((NUM1*NUM2))    #注意此处没有调用$
        echo "$NUM1*$NUM2=$RES"
    done
done
#请把此代码改成C语言格式

 

 

while循环
。语法:
    -while  [条件测试]
      do
            命令
      done
。注意要修改测试条件的值,防止死循环。还可以与if-then-fi嵌套使用,使用exit函数退出
read $1 $2 $3        //可以用来读取文本文件中某一行的第一个,第二个,第三个不规则的参数作为输入
函数的使用
。函数是一系列的指令和命令
。本身不运行,可以多次调用,可以简化代码
。语法
函数()
{
    命令1;命令2
        return    #返回值
}
函数的参数
。函数也可以作为一个程序一样运行,接收参数
-fname $arg1    $arg2
    -这和shell中位置参数一样,我们可以对$1,$2测试

max()
{
    if (($1>$2));then
        return $1    #注意,此时函数已经结束了
    fi    
        return $2
}
max 10 100
echo $?    #通过$?取得函数的返回值
函数示例

setPath()
{
    PATH=/bin:/usr/bin
    if (($UID == 0 ));then    #如果为root
        PATH=$PATH:/usr/bin/sbin:/sbin    #路径追加sbin的目录
    fi
    if (($2 == "after"));then    #根据位置参数2,决定如何添加新路径
        PATH=$PATH:$1    #在原PATH后面追加
    else
        PATH=$1:$PATH    #在原PATH之前添加
    fi
}
getopts命令
。getopts用来检测命令中传递给脚本的有效参数
。通常用在while loop中
。语法:
    -getopts <选项字符串>    <变量1>
。<选项字符串>包含了要识别的选项字符;如果字符前存在"-"(横杠),而此选项期待着有一个参数,他们之间用空格空开。
。每次调用getopts的时候,他讲下一选项设置给<变量1>
。当选项需要参数时,getopts将参数设置给变量OPTARG
。如果选项不正确,返回  ?  给<变量1>
getopts示例

while getopts n:a: opt    #此程序就有-n和-a选项,注意选项字符串尾部的冒号(:)
do
    case "$opt" in
        n)    name="$OPTARG";;
        a)    age="$OPTARG";;
        \?)    echo “Usage:..."
    esac
done
echo ”Welcome $name,you age is $age"

 

 

  

  

  

  

  

  

 

 

 

  

  

  

  

  

   

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

 

 

 

 

 

  

posted @ 2020-10-18 19:15  爱吃山楂果  阅读(820)  评论(0编辑  收藏  举报