• shell编程实战学习(1)


    shell编程实战学习(1)

    一、shell介绍

    1.1.1 什么shell

    1. Shell是一门解释性编程语言 Linux/Unix系统的底层以及基础软件的核心大部分都有涉及Shell脚本的内容,每一个合格的Linux系统管理员和运维工程师,都需要熟练Shell脚本语言的编写,并且能够阅读系统及各类软件Shell脚本内容。
    2. Shell编程是Linux运维人员常用的自动化编程语言,在工作合理的使用Shell编程脚本可以提高工作的效率,减少不必要的重复工作。

    二、Shell实践

    2.1.1 Shell的变量定义

    1. 查看系统默认的Shell类型
    [root@web01 ~]# echo $SHELL
    /bin/bash
    [root@web01 ~]# grep  root /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    [root@web01 ~]# bash --version
    bash --version
    GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
    Copyright (C) 2011 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software; you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.
    
    1. 什么的变量:用一个简单的字符串(或者字符数字)来替代更多更复杂的内容
    2. Linux变量的类型

    1)局部变量(普通变量):编写shell脚本最常用的,变量名是以字母开头加数字或下划线组成的。

    [root@node ~]# a=root
    [root@node ~]# echo $a
    root
    
    [root@node ~]# a=1
    [root@node ~]# b=2
    [root@node ~]# echo $((a + b))
    3
    
    [root@node ~]# A="i am chj"
    [root@node ~]# B=" I in studying linux"
    [root@node ~]# echo $A$B
    i am chj I in studying linux
    
    [root@web01 ~]# x=1
    [root@web01  ~]# echo $x
    1
    [root@web01  ~]# echo $xb
    
    [root@web01 ~]# echo ${x}b
    1b
    
    

    2)全局变量(环境变量):在整个系统中生效、一般为大写字母、是系统中默认就存在的变量,这样的变量是满足系统和程序程序运行的需求。

    [root@web01 ~]# echo $PATH
    echo $PATH
    /application/mysql/bin:/application/nginx/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root/bin:/root/bin
    [root@web01 ~]# echo $HOME
    echo $HOME
    /root
    [root@web01 ~]# echo $UID
    echo $UID
    0
    #自定义环境变量 可以添加到/etc/profile
    [root@web01 ~]# export LINUX=1
    [root@web01 ~]# echo $LINUX
    1
    
    1. 在Linux系统中 ''单引号 ""双引号 不加引号的区别

    1)单引号'' 所见即所得 [root@web01 ~]# echo '$HOME' $HOME
    2)双引号" " 会将内容解析一下 [root@web01 ~]# echo "$HOME" 不加引号 和“”号功能相同

    1. shell变量名的定义:

    一般字母,数字,下划线组成,以字母开头.不能以数字和特殊字符串开头
    '你好?' 内容不会被解析 输出为纯字符串 .原模原样他输出
    "你好?" 如果被赋值给其他变量 不会输出字符串 而是输出变量值 就是说会把变量解析了在输出
    编程好习惯:数字可以不加双""号 ,其它都要默认加上

    1. Shell特殊重要变量
    位置变量 作用说明
    $0 获取当前执行Shell脚本文件名,如果执行脚本带路劲,那就包括脚本路径
    $n 获取当前执行的Shelll脚本的n个参数值,n=1..9,当n为0时表示脚本的文件名,如果n大于9,例如:${10},接的参数咦空格隔开
    $# 获取当前执行的Shell脚本后面接的参数的总个数
    $* 获取当前Shell脚本所有传参参数,不加引号作用同$@;如果给$加上双引号,例如:“$”,则表示将所有的参数视为单个字符串,相当于“$1 $2 $3”
    $@ 获取当前Shell脚本所有传参参数,不加引号作用同$,如果给$@加上双引号,例如:$@,则表示将所有的参数视为不同的独立字符串,相当于 "$1" "$2" "$3" "...", 这是将多参数传递给其他程序的最佳方式,因为他会保留所有内嵌在每个参数里的任何空白。当“$@”和“$” 都加双引号时,二者有区别,都不加双引号时,二者无区别
    $? 检测执行脚本或命令的返回值是否为0(成功) 不为0(失败)
    $$ 获取当前执行脚本的进程号
    $! 获取上一个在后台执行的脚本进程号,了解即可
    $_ 获取在此前执行命令或脚本的最后一个参数,了解即可
    $0
    [root@web01 /server/scripts]# cat arg.sh
    #!/bin/bash
    echo $0
    [root@web01 /server/scripts]# sh arg.sh
    arg.sh
    [root@web01 /server/scripts]# sh /server/scripts/arg.sh 
    /server/scripts/arg.sh
    
    $n
    [root@web01 /server/scripts]# cat arg.sh 
    #!/bin/bash
    echo $0
    echo $1 $2 
    [root@web01 /server/scripts]# sh arg.sh a b 
    arg.sh
    a b
    #不加花括号
    [root@web01 /server/scripts]# cat arg.sh 
    #!/bin/bash
    echo $0
    echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
    [root@web01 /server/scripts]# sh arg.sh {a..z}
    arg.sh
    a b c d e f g h i a0 a1 a2 a3 a4 a5
    #加花括号
    [root@web01 /server/scripts]# cat arg.sh 
    #!/bin/bash
    echo $0
    echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15}
    [root@web01 /server/scripts]# sh arg.sh {a..z}
    arg.sh
    a b c d e f g h i j k l m n o
    
    $#
    [root@web01 /server/scripts]# cat arg.sh 
    #!/bin/bash
    echo $0
    echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15}
    echo $#
    [root@web01 /server/scripts]# sh arg.sh {a..z} 
    arg.sh
    a b c d e f g h i j k l m n o
    26
    [root@web01 /server/scripts]# sh arg.sh a b 
    arg.sh
    a b
    2
    
    $*和$@
    #不加双引号时
    [root@web01 /server/scripts]# for i in $@;do echo $i;done
    I
    am
    linux
    study.
    [root@web01 /server/scripts]# for i in $*;do echo $i;done
    I
    am
    linux
    study.
    #都是三个字符串
    
    #加双引号时
    [root@web01 /server/scripts]# set -- "I am" linux study.
    [root@web01 /server/scripts]# for i in "$*";do echo $i;done
    I am linux study.  #代表一个字符串
    [root@web01 /server/scripts]# for i in "$@";do echo $i;done
    I am
    linux
    study.  #代表三个字符串
    
    $?
    #不为0时
    [root@web01 /server/scripts]# nkir
    -bash: nkir: command not found
    [root@web01 /server/scripts]# echo  $?
    127
    #为0时
    [root@web01 /server/scripts]# ip add
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
        inet6 ::1/128 scope host 
           valid_lft forever preferred_lft forever
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 00:0c:29:ae:f7:fe brd ff:ff:ff:ff:ff:ff
        inet 10.0.0.7/24 brd 10.0.0.255 scope global eth0
           valid_lft forever preferred_lft forever
        inet6 fe80::20c:29ff:feae:f7fe/64 scope link 
           valid_lft forever preferred_lft forever
    3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 00:0c:29:ae:f7:08 brd ff:ff:ff:ff:ff:ff
        inet 172.16.1.7/16 brd 172.16.255.255 scope global eth1
           valid_lft forever preferred_lft forever
        inet6 fe80::20c:29ff:feae:f708/64 scope link 
           valid_lft forever preferred_lft forever
    [root@web01 /server/scripts]# echo  $?
    0
    
    $$
    [root@web01 /server/scripts]# cat arg.sh 
    #!/bin/bash
    echo $*
    echo $@
    echo $$  #脚本中可以这样写 echo $$|tee /tmp/sh.pid 不但输出到屏幕上而且输出到sh.pid里
    [root@web01 /server/scripts]# sh arg.sh 1 3
    1 3
    1 3
    3165        #这就是进程号
    #扩展tee命令介绍
    Linux tee命令用于读取标准输入的数据,并将其内容输出成文件。
    tee指令会从标准输入设备读取数据,将其内容输出到标准输出设备,同时保存成文件。
        -a或--append  附加到既有文件的后面,而非覆盖它.
        -i或--ignore-interrupts  忽略中断信号。
        --help  在线帮助。
        --version  显示版本信息。
    [root@web01 /server/scripts]# echo "linux"|tee /tmp/linux.log
    linux
    [root@web01 /server/scripts]# cat /tmp/linux.log 
    linux
    
    1. Shell 变量子串的应用
    表达式 说明
    ${parameter} 返回变量$parameter的内容
    ${#parameter} 返回变量$parameter内容的长度(按字符),也适用于特殊变量
    ${parameter:offset} 在变量${parameter}中,从位置offset之后开始提取子串到结尾
    ${parameter:offset:length} 在变量${parameter}中,从位置offset之后开始提取长度为length的子串
    ${parameter#word} 从变量${parameter}开头开始删除最短匹配的word子串
    ${parameter##word} 从变量${parameter}开头开始删除最长匹配的word子串
    ${parameter%word} 从变量${parameter}结尾开始删除最短匹配的word子串
    ${parameter%%word} 从变量${parameter}结尾开始删除最长匹配的word子串
    ${parameter/pattern/string} 使用string代替第一个匹配的pattern
    ${parameter//pattern/string} 使用string代替所有匹配的pattern
    #打印内容
    [root@web01 /server/scripts]# OLDBOY="I am oldboy"
    [root@web01 /server/scripts]# echo ${OLDBOY}
    I am oldboy
    
    #打印字符长度
    [root@web01 /server/scripts]# OLDBOY="I am oldboy"
    [root@web01 /server/scripts]# echo ${#OLDBOY}
    11
    
    #截取内容
    [root@web01 /server/scripts]# OLDBOY="I am oldboy"
    [root@web01 /server/scripts]# echo ${OLDBOY}
    I am oldboy
    [root@web01 /server/scripts]# echo ${OLDBOY:2:2}
    am
    [root@web01 /server/scripts]# echo ${OLDBOY:2}
    am oldboy
    
    #删除
    #(从开头删)
    {parameter#word}	从变量${parameter}【开头】开始删除最【短】匹配的word子串
    [root@web01 /server/scripts]# OLDBOY=abcABC123ABCabc
    [root@web01 /server/scripts]# echo $OLDBOY
    abcABC123ABCabc
    [root@web01 /server/scripts]# echo ${OLDBOY#a*C}
    123ABCabc
    {parameter##word}	从变量${parameter}【开头】开始删除最【长】匹配的word子串
    [root@web01 /server/scripts]# OLDBOY=abcABC123ABCabc
    [root@web01 /server/scripts]# echo $OLDBOY
    abcABC123ABCabc
    [root@web01 /server/scripts]# echo ${OLDBOY##a*C}
    abc
    #(从结尾删)
    {parameter%word}	从变量${parameter}结尾开始删除最短匹配的word子串
    [root@web01 /server/scripts]# OLDBOY=abcABC123ABCabc
    [root@web01 /server/scripts]# echo ${OLDBOY%a*c}
    abcABC123ABC
    {parameter%%word}	从变量${parameter}结尾开始删除最长匹配的word子串
    [root@web01 /server/scripts]# OLDBOY=abcABC123ABCabc
    [root@web01 /server/scripts]# echo ${OLDBOY%%A*c}
    abc
    
    #单个匹配替换
    [root@web01 /server/scripts]# OLDBOY="I am oldboy ,yes oldboy"
    [root@web01 /server/scripts]# echo ${OLDBOY}
    I am oldboy ,yes oldboy
    [root@web01 /server/scripts]# echo ${OLDBOY/oldboy/oldgirl}
    I am oldgirl ,yes oldboy
    #全部匹配替换
    [root@web01 /server/scripts]# OLDBOY="I am oldboy ,yes oldboy"
    [root@web01 /server/scripts]# echo ${OLDBOY}
    I am oldboy ,yes oldboy
    [root@web01 /server/scripts]# echo ${OLDBOY//oldboy/oldgirl}
    I am oldgirl ,yes oldgirl
    

    8.面试题

    #利用shell脚本打印出字符照度小于6的单词 I am oldboy linux welcome to our training.
    [root@web01 /server/scripts]# cat count.sh 
    chars="I am oldboy linux welcome to our training."
    
    for i in $chars
    do 
      if [ ${#i} -lt 6 ]
       then
       echo $i
    fi
    done
    [root@web01 /server/scripts]# sh count.sh
    I
    am
    linux
    to
    our
    
    [root@web01 /server/scripts]# test=lele
    [root@web01 /server/scripts]# echo $test
    lele
    [root@web01 /server/scripts]# result=${test:-unset}
    [root@web01 /server/scripts]# echo $result
    lele
    [root@web01 /server/scripts]# unset test
    [root@web01 /server/scripts]# echo $test
    
    [root@web01 /server/scripts]# result=${test:-unset}
    [root@web01 /server/scripts]# echo $result
    unset
    #实例删除脚本
    [root@web01 /server/scripts]# cat del.sh 
    #!/bin/bash
    DIR=/opt/
    
    find ${DIR:-/tmp/} -name "*.tar.gz" -type f -mtime +7 |xargs rm -fr
    rm -rf ${DIR:-/tmp/}   
    [root@web01 /server/scripts]# ll /opt
    ls: cannot access /opt: No such file or directory
    [root@web01 /server/scripts]# cat del.sh 
    #!/bin/bash
    #DIR=/opt/      #如果将DIR变量注释掉,就会删除tmp目录
    find ${DIR:-/tmp/} -name "*.tar.gz" -type f -mtime +7 |xargs rm -fr
    rm -rf ${DIR:-/tmp}
    [root@web01 /server/scripts]# sh -x del.sh 
    + xargs rm -fr
    + find /tmp/ -name '*.tar.gz' -type f -mtime +7
    + rm -rf /tmp
    

    2.1.2 变量数值计算

    1. 计算符号
    计算符号 意义
    + 、- 加 减
    *、/ 、% 乘法 除法 取模
    ** 幂运算
    ++、-- 增加及减少,可前置也可放在变量结尾,默认步长为1
    !、&&、|| 逻辑非(取反)、逻辑与(and)、逻辑或(or)
    <、<=、>、>= 比较符号 (小于、小于等于、大于、大于等于)
    ==、!=、= 比较符号 (相等 、不等于、对于字符串“=”也可以表示相当)
    << 、>> 向左移位、向右移位
    ~、|、&、^ 按为取反、按位异或、按位与、按位或
    =、+=、-=、*=、/=、%= 赋值运算符,列如a+=1相当于a=a+1,a-=1相当于a=a-1
    1. Shell 的常见算术运算命令
    运算操作符与命令 作用
    (()) 用于整数运算的常用运算符,效率很高
    let 用于整数运算,类似(())
    expr 可用于整数运算,但还有很多其它的额外功能
    bc Linux下的一个计算器程序(适合整数以及小数运算)
    $[] 用于整数运算
    awk awk 即可用于整数运算,也可以用于小数运算
    declare 定义变量数值和属性,-i参数可以用于定义整形变量,做运算
    1. 运算实战
    #(())
    [root@web01 /server/scripts]# ((a=1+10))
    [root@web01 /server/scripts]# echo $a
    11
    
    #let
    [root@web01 /server/scripts]# a=1
    [root@web01 /server/scripts]# let a=a+1
    [root@web01 /server/scripts]# echo $a
    2
    
    #expr
    [root@web01 /server/scripts]# expr 2 + 3
    5
    [root@web01 /server/scripts]# expr 2 - 3
    -1
    [root@web01 /server/scripts]# expr 2 / 3
    0
    
    #bc
    [root@web01 /server/scripts]# echo 1 + 3 |bc
    4
    [root@web01 /server/scripts]# echo 3-2 |bc
    1
    [root@web01 /server/scripts]# echo 3 - 2 |bc
    1
    [root@web01 /server/scripts]# echo 3 / 2 |bc
    1
    [root@web01 /server/scripts]# echo 1.2 + 1.8 |bc
    3.0
    
    #$[]
    [root@web01 /server/scripts]# echo $[20+30]
    50
    [root@web01 /server/scripts]# echo $[20/30]
    0
    [root@web01 /server/scripts]# echo $[20*30]
    600
    
    #awk
    [root@web01 /server/scripts]# echo 5 6|awk '{print $1*$2}'
    30
    [root@web01 /server/scripts]# echo 5.2 6|awk '{print $1*$2}'
    31.2
    [root@web01 /server/scripts]# echo 2 6|awk '{print $1**$2}'
    64
    [root@web01 /server/scripts]# echo 5 6|awk '{print $1-$2}'
    -1
    [root@web01 /server/scripts]# echo 6 5|awk '{print $1/$2}'
    1.2
    [root@web01 /server/scripts]# echo 6 5|awk '{print $1%$2}'
    1
    
    #declare
    [root@web01 /server/scripts]# declare -i a=10+30
    [root@web01 /server/scripts]# echo $a
    40
    [root@web01 /server/scripts]# declare -i a=10*30
    [root@web01 /server/scripts]# echo $a
    300
    

    2.1.3 expr的功能

    1. 计算
    [root@web01 /server/scripts]# expr 1 + 3
    4
    
    1. 获取字符串长度功能
    [root@web01 /server/scripts]# expr length "linux"
    5
    
    1. 判断字符串是否为数字或字符
    [root@web01 /server/scripts]# a=1
    [root@web01 /server/scripts]# expr $a + k &>/dev/null
    [root@web01 /server/scripts]# echo $?
    2
    [root@web01 /server/scripts]# expr $a + 1 &>/dev/null
    [root@web01 /server/scripts]# echo $?
    0
    
    1. 用来判断文件扩展名是否符合指定扩展名
    [root@web01 /server/scripts]# cat jubeo.sh 
    #!/bin/bash
    if expr "$1" : ".*.avi$" >/dev/null ; then
       echo "好兴奋啊"
    else
        echo "好失望啊"
    fi
    [root@web01 /server/scripts]# sh jubeo.sh linx.avi
    好兴奋啊
    [root@web01 /server/scripts]# sh jubeo.sh linx.loj
    好失望啊
    
  • 相关阅读:
    google glog 使用方法
    LIBRARY_PATH和LD_LIBRARY_PATH环境变量的区别
    c++ ‘nullptr’ 在此作用域中尚未声明
    Impala 使用的端口
    忽略“Signal: SIGSEGV (Segmentation fault)”
    查看python脚本的运行pid,让python脚本后台运行
    阿里云主机运行速度慢的解决办法
    在Git.oschina.net中配置TortoiseGit使用sshkey,无需输入账号和密码
    抓取国家的学校编码数据
    CAS统一登录认证好文汇集贴
  • 原文地址:https://www.cnblogs.com/woaiyunwei/p/12942094.html
Copyright © 2020-2023  润新知