Linux学习记录(四)Shell编程

Linux学习记录(四)Shell编程


0、学习shell的目的:

  • 方便运维;
  • 编写shell程序管理集群、提高开发效率;

1、Shell概述

(1)shell是解释器;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gDD90oIN-1653397751774)(C:\Users\聂志伟\AppData\Roaming\Typora\typora-user-images\image-20220523152115701.png)]

​ 核心:硬件系统(主机+外设);

​ 外层:操作系统;

​ 内核:操作系统的核心——直接操作硬件(对用户不友好)

​ 外层:用户接口,操作系统一部分(文本编辑器、浏览器等、ls命令等),KED, GNOME等;用户可

​ 以操作,但内核不能理解

​ Shell:解释层,将用户命令转换为内核命令

(2)Shell是命令行解释器,用于接受用户(程序)命令,然后调用系统内核;

(3)脚本: 在Linux系统中,可以将命令逐条解释执行,也可以将多条命令放到一个文件中,交由系统执行。这样的文件称脚本。

总结:Shell还是一个功能强大的编程语言,易编写,易调试,灵活性强


2、Shell环境

Shell 编程跟 JavaScript、php 编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。

Linux 的 Shell 种类众多,常见的有:

  • Bourne Shell(/usr/bin/sh或/bin/sh)
  • Bourne Again Shell(/bin/bash)
  • C Shell(/usr/bin/csh)
  • K Shell(/usr/bin/ksh)
  • Shell for Root(/sbin/sh)
  • ……

本教程关注的是 Bash,也就是 Bourne Again Shell,由于易用和免费,Bash 在日常工作中被广泛使用。同时,Bash 也是大多数Linux 系统默认的 Shell。

在一般情况下,人们并不区分 Bourne Shell 和 Bourne Again Shell,所以,像 #!/bin/sh,它同样也可以改为 #!/bin/bash

告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序


3、Shell解析器

  • Linux提供的Shell解析器:

    [root@localhost ~]# cat /etc/shells
    /bin/sh
    /bin/bash
    /sbin/nologin
    /usr/bin/sh
    /usr/bin/bash
    /usr/sbin/nologin
    
  • Bash和sh的关系:

    [root@localhost ~]# cd /bin/
    [root@localhost bin]# ll | grep bash
    -rwxr-xr-x. 1 root root    960472 83 2017 bash
    lrwxrwxrwx. 1 root root        10 521 12:58 bashbug -> bashbug-64
    -rwxr-xr-x. 1 root root      6964 83 2017 bashbug-64
    lrwxrwxrwx. 1 root root         4 521 12:58 sh -> bash
    
    # sh最后转为bash去解析,所以一般不区分sh与bash
    
  • CentOS默认的解析器是bash;

    [root@localhost bin]# echo $SHELL
    /bin/bash
    

4、Shell脚本入门

  • 脚本格式:以 # !/bin/bash 开头(指定解析器)

  • 第一个shell脚本:helloworld

    (1)脚本代码:

    # !/bin/bash
    echo "hello,world!"
    echo "This is the first shell application."
    

    (2)脚本执行方式:

    ​ ① bash / sh + 相对路径/绝对路径(解析器执行不用赋予脚本 + x 权限)

    [root@localhost c-work]# bash /root/vscode-work/c-work/hello.sh
    hello,world!
    This is the first shell application.
    
    [root@localhost c-work]# sh hello.sh
    hello,world!
    This is the first shell application.
    

    ​ ② . / hello.sh (需要赋予sh文件权限:chmod 777 hello.sh

    [root@localhost c-work]# chmod 777 hello.sh
    [root@localhost c-work]# ./hello.sh
    hello,world!
    This is the first shell application.
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zH1DH2g8-1653397751775)(C:\Users\聂志伟\AppData\Roaming\Typora\typora-user-images\image-20220523160201244.png)]

  • 多命令处理

    [root@localhost c-work]# touch batch.sh
        #!/bin/bash
        cd /root/vscode-work/c-work/
        touch batchdemo.txt
        echo "i love aust" >> batchdemo.txt
        # >> 重定向到文件
    [root@localhost c-work]# cat batchdemo.txt
    i love aust
    

5、Shell变量

系统变量
  • 常用系统变量: H M O E , HMOE, HMOEPWD, S H E L L , SHELL, SHELLUSER等

  • 实操案例

    • # 查看系统变量
      [root@localhost c-work]# echo $HOME
      /root
      
    • # 显示当前Shell中所有变量
      [root@localhost c-work]# set
      BASH=/bin/bash
      BASH_ALIASES=()
      BASH_ARGC=()
      BASH_ARGV=()
      BASH_CMDS=()
      BASH_LINENO=()
      BASH_SOURCE=()
      
自定义变量
  • 基本语法:

    • 定义变量:变量=值(不含空格)

      [root@localhost c-work]# A=2
      [root@localhost c-work]# echo $A
      2
      
    • 只读变量:readonly 变量名=值(不可修改)

      [root@localhost c-work]# readonly A=1
      [root@localhost c-work]# A=2
      -bash: A: 只读变量
      
      # 删除只读变量
      [root@localhost c-work]# cat << EOF | gdb
      > attach $$
      > call unbind_variable("变量名")
      > detach
      > EOF
      
    • 全局变量:export 变量名=值(可供其他shell程序使用)

      [root@localhost c-work]# D="這是變量D"
      [root@localhost c-work]# ./hello.sh
      hello,world!
      This is the first shell application.
      [root@localhost c-work]# export D
      [root@localhost c-work]# ./hello.sh
      hello,world!
      This is the first shell application.
      這是變量D
      
    • 撤销变量:unset 变量

      [root@localhost c-work]# unset A
      [root@localhost c-work]# echo $A
      
      
    • 引用变量:$变量名

      注意:在bash中,变量默认字符串类型,无法直接进行数值运算;

特殊变量$n
  • 功能描述:n为数字,$0代表脚本名称,$1- 9 代 表 第 一 到 第 九 个 参 数 , 10 以 上 用 9代表第一到第九个参数,10以上用 910{12} ;

  • 实例:

    [root@localhost c-work]# touch prm.sh
    [root@localhost c-work]# vi prm.sh
    	# 代码段
    	#!/bin/bash
    	echo "$0 $1 $2 $3"
    [root@localhost c-work]# sh prm.sh
    prm.sh   
    [root@localhost c-work]# sh prm.sh love
    prm.sh love  
    [root@localhost c-work]# sh prm.sh love ppp
    prm.sh love ppp 
    
特殊变量$#
  • 功能描述:获取所有输入参数个数,常用于循环
  • 实例:
特殊变量 ∗ 、 *、 @
  • 功能描述:获取所有位置参数内容; ∗ 把 所 有 参 数 看 成 一 个 整 体 、 * 把所有参数看成一个整体、 @把每个参数区分对待

  • 实例:

    [root@localhost c-work]# touch prm1.sh
    [root@localhost c-work]# vi prm1.sh
        #!/bin/bash
        echo "$0 $1 $2 $3"
        echo $#
        echo $*
        echo $@
    [root@localhost c-work]# sh prm1.sh 1 2 3
    prm1.sh 1 2 3
    3
    1 2 3
    1 2 3
    
特殊变量$?
  • 功能描述:最后一次执行的命令的返回值状态,0表示上一命令正确执行,非0表示不正确执行

  • 实例:

    [root@localhost c-work]# ./hello.sh
    hello,world!
    This is the first shell application.
    
    [root@localhost c-work]# echo $?
    0
    

6、Shell运算符

基本语法:

  • ( ( 运 算 式 ) ) ” 或 “ ((运算式))”或“ [运算式]”
  • expr +,-,\*,/,% 加减乘除取余
  • 注意:expr 运算符之间必须有空格

运算实例:

  • 计算4+5的值

    [root@localhost c-work]# expr 4 + 5
    9
    
  • 计算(2+3)*4的值

    • expr一步计算
    [root@localhost c-work]# expr `expr 2 + 3` \* 4
    20
    
    • $[运算式]方式
    [root@localhost c-work]# echo $[(2+3)*4]
    20
    

7、Shell条件判断

基本语法:

  • [ condition ]前后要有空格
  • 条件非空即为true,[atguigu]返回true,[]返回false

常用条件判断:

  • 两个数字之间的比较=字符串比较

    -lt 小于(less than)
    -le 小于等于(less equal)
    -eq 等于(equal)
    -gt 大于(greater than)
    -ge 大于等于(greater equal)
    -ne 不等于(not equal)
    
  • 按照文件权限进行判断

    -r 有读的权限(read)
    -w 有写的权限(write)
    -x 有执行的权限(execute)
    
  • 按照文件类型进行判断

    -f 文件存在且是一个常规文件(file)
    -e 文件存在(existence) 
    -d 文件存在并且是一个目录(directory)
    
  • 多条件判断:

    • &&表示前一条命令执行成功时才执行后一条命令
    • || 表示上一条命令执行失败后才执行下一条命令

8、流程控制

if 判断
  • 基本语法:

    if [ 条件表达式 ];then
    	程序
    fi
    或者
    if [ 条件表达式 ]
    	then
    		程序
    fi
    #注意:[ 条件表达式 ]必须有空格
    #if 后要有空格
    if [ 条件表达式 ]
    then
    	程序
    elif [ 条件表达式 ]
    then 
    	程序
    else
    	程序
    fi
    
    #!/bin/bash
    echo Enter a number:
    read NUM
    if [ $NUM -eq 1 ]
    then
            echo this is 1
    elif [ $NUM -eq 2 ]
    then
            echo this is 2
    else
            echo no!
    fi
    
    [root@localhost vscode-work]# sh if.sh
    Enter a number:
    1
    this is 1
    [root@localhost vscode-work]# sh if.sh
    Enter a number:
    3
    no!
    
case 分支语句
  • 基本语法:

    case $变量名 in
    “值1”)
    	程序
    	;;
    “值2”)
    	程序
    	;;	
    ...省略其他case分支...
    *)
    	如果以上都未执行,则执行此处程序
    esac
    
    
    #!/bin/bash
    echo enter a munber
    read NUM
    case $NUM in
    "1")
            echo this is 1
            ;;
    "2")
            echo this is 2
            ;;
    *)
            echo this is none
            ;;
    esac
    
    
    [root@localhost vscode-work]# ./case.sh
    enter a munber
    0
    this is none
    [root@localhost vscode-work]# ./case.sh
    enter a munber
    2
    this is 2
    
for循环
  • 基本语法:

    for 变量名 in 数值1 数值2 数值3...
    do
    	程序
    done
    或者
    for ((初始值;条件;值变化))
    do
    	循环执行的命令串
    done
    
    #从1加到10
    #!/bin/bash
    s=0
    for ((i=1;i<=10;i++))
    do
            s=$[$s+$i]
    done
    echo $s
    
    [root@localhost vscode-work]# sh for.sh
    55
    -----------------------------------------
    #!/bin/bash
    echo this is "$""*"
    for i in $*
    do 
            echo  "bbb $i"
    done
    echo this is "$""@"
    for j in $@
    do 
    
            echo "bbb $j"
    
    done
    
    [root@localhost vscode-work]# sh forest.sh 1 2 3 
    this is $*
    bbb 1
    bbb 2
    bbb 3
    this is $@
    bbb 1
    bbb 2
    bbb 3
    
    
while循环语法
  • 基本语法:

    while 循环条件命令串
    do
    	循环执行的命令串
    done
    
    #计算1-9的平方
    #!/bin/bash
    R=1
    while [ $R -le 9 ]
    do
            RE=`expr $R\*$R`
            echo $R * $R = $RE
            R=`expr $R + 1`
    done
    
    [root@localhost vscode-work]# sh while.sh
    1 case.sh c-work for.sh if.sh shell while.sh 1 = 1*1
    2 case.sh c-work for.sh if.sh shell while.sh 2 = 2*2
    3 case.sh c-work for.sh if.sh shell while.sh 3 = 3*3
    4 case.sh c-work for.sh if.sh shell while.sh 4 = 4*4
    5 case.sh c-work for.sh if.sh shell while.sh 5 = 5*5
    6 case.sh c-work for.sh if.sh shell while.sh 6 = 6*6
    7 case.sh c-work for.sh if.sh shell while.sh 7 = 7*7
    8 case.sh c-work for.sh if.sh shell while.sh 8 = 8*8
    9 case.sh c-work for.sh if.sh shell while.sh 9 = 9*9
    
read读入控制台输入
  • 基本语法:read(选项)(参数)

    • 选项:-p:指定读取值的提示符

      ​ -t:指定读取值时等待的时间(秒)

    • 参数:变量:指定读取值的变量名


9、函数

系统函数
  • basename 基本语法:删掉所有前缀、包括最后一个字符,然后将字符串显示出来

  • basename [string/pathname] [suffix]:如果suffix后缀被指定,则会把string/pathname中后缀去掉

  • 可以对多个符号串同时处理(使用-a参数)

    [root@localhost vscode-work]# basename /root/vscode-work/ban.txt
    ban.txt
    [root@localhost vscode-work]# basename /root/vscode-work/ban.txt .txt
    ban
    
  • dirname 基本语法:从给定的文件路径中,去掉文件名,只返回路径

    [root@localhost vscode-work]# dirname /root/vscode-work/ban.txt .txt
    /root/vscode-work
    
自定义函数
  • 基本语法:

    function funname[()]
    {
    	程序
    	return 返回值
    }
    funname
    
    # 在调用之前声明函数,shell脚本是逐行执行,不会编译
    # 函数可以有返回值(通常0~255),也可以没有返回值,这时,shell以函数中最后一条命令的执行结果作为函数返回结果
    

10、Shell工具(重点)

awk
  • 功能描述:把文件逐行读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理;

    ​ 非交互处理工具awk:基于模式匹配算法的文本行处理算法,支持print

  • 基本用法:

    awk 选项 ’pattern{action}...' filename
    pattern:表示awk在数据中查找到的内容,即匹配模式(可不写,无匹配查找)
    action:在找到匹配内容时执行的一系列命令
    # 例如↓
    # 在/etc/passwd文件中,以''为分隔符,打印第1,第2列
    awk -F ":" '{print $1, $2}' /etc/passwd 
    awk -F: '{print $1":" $2}' /etc/passwd 
    

    参数说明:

    选项参数功能描述
    - F指定文件拆分符号
    - v赋值一个用户定义变量
    - f表示调用awk脚本处理,f 后跟脚本文件
  • 代码实现:

    [root@localhost awk]# cp /etc/passwd ./ # 拷贝passwd文件到当前目录
    [root@localhost awk]# ls
    passwd
    [root@localhost awk]# cat passwd
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    sync:x:5:0:sync:/sbin:/bin/sync
    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    halt:x:7:0:halt:/sbin:/sbin/halt
    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    operator:x:11:0:operator:/root:/sbin/nologin
    games:x:12:100:games:/usr/games:/sbin/nologin
    ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
    nobody:x:99:99:Nobody:/:/sbin/nologin
    systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
    dbus:x:81:81:System message bus:/:/sbin/nologin
    polkitd:x:999:997:User for polkitd:/:/sbin/nologin
    postfix:x:89:89::/var/spool/postfix:/sbin/nologin
    sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
    chrony:x:998:996::/var/lib/chrony:/sbin/nologin
    nzw:x:1000:1000:nzw:/home/nzw:/bin/bash
    root123:x:1001:1001::/home/root123:/bin/bash
    
    # 搜索passwd文件义root关键字开头的所有行,并输出该行的第1列和第7列,中间以“,”分割
    [root@localhost awk]# awk -F: '/^root/{print $1","$7}' passwd
    root,/bin/bash
    root123,/bin/bash
    
    # 搜索passwd文件义root关键字开头的所有行,并输出该行的第1列和第7列,中间以“,”分割
    # 所有行前面添加列user,shell,在最后一行添加“BBB,PPP”
    [root@localhost awk]# awk -F: 'BEGIN{print "user,shell"}/^root/{print$1","$7}END{print "BBBB,PPP"}' passwd
    user,shell
    root,/bin/bash
    root123,/bin/bash
    BBBB,PPP
    #BEGIN在所有数据读取之前执行,END在所有数据操作之后执行
    
    # 切分IP地址
    [root@localhost ~]# ifconfig ens33 | grep "inet" | awk -F " " '{print $2}'
    192.168.146.140
    fe80::316b:ac5c:b6f1:cae2
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u2lY6voj-1653397751775)(C:\Users\聂志伟\AppData\Roaming\Typora\typora-user-images\image-20220524200849523.png)]

sed
  • 功能描述:文本流处理工具,默认不修改源文件,在缓冲区中进行修改,将修改后结果提供给用户;

    详细解释

    sed是一种流编辑器,一次处理一行内容。处理时把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区的内容,处理完成后,把缓冲区的内容送往屏幕,接着再处理下一行,知道文件末尾。

    注意:这里的文件内容没有改变,除非使用重定向存储输出;

  • 基本用法:

    sed 选项参数 ‘comand’ filename
    # 常使用带前置命令的如下
    comand | sed 选项参数 ‘comand’ filename
    

    选项参数:

    选项参数功能描述
    - n屏蔽默认输出(全部内容)
    - i直接修改文件内容(不仅仅是在缓冲区修改)
    - f指定sed脚本进行处理,后跟脚本文件
    - e指定多个操作动作
    - r启用扩展的正则表达式,要在所有参数最前面使用
    {}组合多个命令,用分号区分

    命令功能:

    命令功能
    p打印行
    d删除行
    s字符替换

    命令详解

    p:打印行 ‘2, 4p’:打印第2~4行;‘2p; 4p’:打印第2行,第4行

    d:删除行 ‘2, 4d’:删除第2~4行

    s:字符替换

    s/newword/oldword/:用新内容替换旧内容一次(每行第一次出现)

    s/newword/oldword/3:用新内容替换旧内容1次(每行第三次出现)

    s/newword/oldword/g:用新内容替换所有旧内容

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

克洛哀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值