• Linux之Shell(二)


    函数

    系统函数

    basename

    • 基本语法

      basename [string / pathname] [suffix] 功能描述:basename 命令会删掉所有的前缀包括最后一个(‘/’)字符,然后将字符串显示出来

      basename可以理解为取路径文件里的文件名称

      选项:

      suffix 为后缀,如果 suffix 被指定了,basename 会将 pathname 或 string 中的 suffix 去掉

    • 案例实操

      截取该/home/guozihan/banzhang.txt 路径的文件名

      [guozihan@hadoop100 program]$ basename /home/guozihan/banzhang.txt
      banzhang.txt
      [guozihan@hadoop100 program]$ basename /home/guozihan/banzhang.txt .txt
      banzhang
      
      • 1
      • 2
      • 3
      • 4

    dirname

    • 基本语法

      dirname 文件绝对路径 功能描述:从给定的包含绝对路径的文件名中去除文件名 (非目录的部分),然后返回剩下的路径(目录的部分)

      dirname 可以理解为取文件路径的绝对路径名称

    • 案例实操

      获取 banzhang.txt 文件的路径

      [guozihan@hadoop100 program]$ dirname /home/guozihan/banzhang.txt
      /home/guozihan
      
      • 1
      • 2

    自定义函数

    • 基本语法

      [ function ] funname[()]
      {
      	Action;
      	[return int;]
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
    • 经验技巧

      • 必须在调用函数地方之前,先声明函数,shell 脚本是逐行运行。不会像其它语言一 样先编译。
      • 函数返回值,只能通过$?系统变量获得,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。return 后跟数值 n(0-255)
    • 案例实操

      计算两个输入参数的和

      [guozihan@hadoop100 program]$ touch fun.sh
      [guozihan@hadoop100 program]$ vim fun.sh 
      
      • 1
      • 2
      #!/bin/bash
      function sum()
      {
      s=0
      s=$[$1+$2]
      echo "$s"
      }
      read -p "Please input the number1: " n1;
      read -p "Please input the number2: " n2;
      sum $n1 $n2;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      [guozihan@hadoop100 program]$ chmod 777 fun.sh
      [guozihan@hadoop100 program]$ ./fun.sh 
      Please input the number1:2
      Please input the number2:5
      7
      
      • 1
      • 2
      • 3
      • 4
      • 5

    正则表达式入门

    正则表达式使用单个字符串来描述、匹配一系列符合某个语法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。在 Linux 中,grep, sed,awk 等文本处理工具都支持通过正则表达式进行模式匹配

    常规匹配

    一串不包含特殊字符的正则表达式匹配它自己

    [guozihan@hadoop100 program]$ cat /etc/passwd | grep guozihan
    guozihan:x:1000:1000:Guozihan:/home/guozihan:/bin/bash
    
    • 1
    • 2

    就会匹配所有包含 guozihan 的行

    常用特殊字符

    • 特殊字符:^

      ^ 匹配一行的开头

      [guozihan@hadoop100 program]$ cat /etc/passwd | grep ^a
      adm:x:3:4:adm:/var/adm:/sbin/nologin
      abrt:x:173:173::/etc/abrt:/sbin/nologin
      avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
      
      • 1
      • 2
      • 3
      • 4

      会匹配出所有以 a 开头的行

    • 特殊字符:$

      $ 匹配一行的结束

      [guozihan@hadoop100 program]$ cat /etc/passwd | grep t$
      halt:x:7:0:halt:/sbin:/sbin/halt
      
      • 1
      • 2

      会匹配出所有以 t 结尾的行

    • 特殊字符:.

      . 匹配一个任意的字符

      [guozihan@hadoop100 program]$ cat /etc/passwd | grep r..t
      root:x:0:0:root:/root:/bin/bash
      operator:x:11:0:operator:/root:/sbin/nologin
      ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
      
      • 1
      • 2
      • 3
      • 4

      会匹配包含 rabt,rbbt,rxdt,root等的所有行

    • 特殊字符:*

      * 不单独使用,他和上一个字符连用,表示匹配上一个字符 0 次或多次

      [guozihan@hadoop100 program]$ cat /etc/passwd | grep ro*t
      root:x:0:0:root:/root:/bin/bash
      operator:x:11:0:operator:/root:/sbin/nologin
      abrt:x:173:173::/etc/abrt:/sbin/nologin
      rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin
      
      • 1
      • 2
      • 3
      • 4
      • 5

      会匹配 rt, rot, root, rooot, roooot 等所有行

    • 字符区间(中括号):[ ]

      [ ] 表示匹配某个范围内的一个字符

      [6,8]------匹配 6 或者 8

      [0-9]------匹配一个 0-9 的数字

      [0-9]*------匹配任意长度的数字字符串

      [a-z]------匹配一个 a-z 之间的字符

      [a-z]* ------匹配任意长度的字母字符串

      [a-c, e-f]-匹配 a-c 或者 e-f 之间的任意字符

      [guozihan@hadoop100 program]$ cat /etc/passwd | grep r[a,b,c]*t
      operator:x:11:0:operator:/root:/sbin/nologin
      abrt:x:173:173::/etc/abrt:/sbin/nologin
      rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin
      sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
      
      • 1
      • 2
      • 3
      • 4
      • 5

      会匹配 rt,rat, rbt, rabt, rbact,rabccbaaacbt等等所有行

    • 特殊字符:\

      \ 表示转义,并不会单独使用。由于所有特殊字符都有其特定匹配模式,当我们想匹配某一特殊字符本身时(例如,我想找出所有包含 ‘$’ 的行),就会碰到困难。此时我们就要将转义字符和特殊字符连用,来表示特殊字符本身

      [guozihan@hadoop100 program]$ cat /etc/passwd | grep 'a\$b'
      
      • 1

      就会匹配所有包含 a$b 的行。注意需要使用单引号将表达式引起来

    文本处理工具

    cut

    cut 的工作就是“剪”,具体的说就是在文件中负责剪切数据用的。cut 命令从文件的每 一行剪切字节、字符和字段并将这些字节、字符和字段输出

    • 基本用法

      cut [选项参数] filename

      说明:默认分隔符是制表符

    • 选项参数说明

      -f 列号,提取第几列 +

      -d 分隔符,按照指定分隔符分割列,默认是制表符“\t”

      -c 按字符进行切割后加加 n 表示取第几列 比如 -c 1

    • 案例实操

      数据准备

      [guozihan@hadoop100 program]$ touch cut.txt
      [guozihan@hadoop100 program]$ vim cut.txt
      
      • 1
      • 2
      dong shen
      guan zhen
      wo wo
      lai lai
      le le
      
      • 1
      • 2
      • 3
      • 4
      • 5

      切割cut.txt第一列

      [guozihan@hadoop100 program]$ cut -d " " -f 1 cut.txt
      dong
      guan
      wo
      lai
      le
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

      切割cut.txt第二、三列

      [guozihan@hadoop100 program]$ cut -d " " -f 2,3 cut.txt
      shen
      zhen
      wo
      lai
      le
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

      在cut.txt文件中切割出guan

      [guozihan@hadoop100 program]$ cat cut.txt | grep guan | cut -d " " -f 1
      guan
      
      • 1
      • 2

      选取系统 PATH 变量值,第 2 个“:”开始后的所有路径

      [guozihan@hadoop100 program]$ echo $PATH
      /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/guozihan/.local/bin:/home/guozihan/bin
      [guozihan@hadoop100 program]$ echo $PATH | cut -d ":" -f 3-
      /usr/local/sbin:/usr/sbin:/home/guozihan/.local/bin:/home/guozihan/bin
      
      • 1
      • 2
      • 3
      • 4

      切割 ifconfig 后打印的 IP 地址

      [guozihan@hadoop100 program]$ ifconfig ens33 | grep netmask | cut -d " " -f 10 
      192.168.182.100
      
      • 1
      • 2

    awk

    一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理

    • 基本用法

      awk [选项参数] ‘/pattern1/{action1} /pattern2/{action2}…’ filename

      pattern:表示 awk 在数据中查找的内容,就是匹配模式

      action:在找到匹配内容时所执行的一系列命令

    • 选项参数说明

      -F 指定输入文件分隔符

      -v 赋值一个用户定义变量

    • 注意

      只有匹配了 pattern 的行才会执行 action。

      [atguigu@hadoop101 shells]$ awk -F : 'BEGIN{print "user, shell"} {print $1","$7} END{print "dahaige,/bin/zuishuai"}' passwd
      user, shell
      root,/bin/bash
      bin,/sbin/nologin 。。。
      atguigu,/bin/bash
      dahaige,/bin/zuishuai
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

      BEGIN 在所有数据读取行之前执行;END 在所有数据执行之后执行。

    • awk的内置变量

      FILENAME 文件名

      NR 已读的记录数(行号

      NF 浏览记录的域的个数(切割后,列的个数

    • 实例实操

      查询 ifconfig 命令输出结果中的空行所在的行号

      [guozihan@hadoop100 program]$ ifconfig | awk '/^$/{print NR}'
      9
      18
      25
      
      • 1
      • 2
      • 3
      • 4

      切割 IP

      [guozihan@hadoop100 program]$ ifconfig ens33 | awk '/netmask/ {print $2}'
      192.168.182.100
      
      • 1
      • 2

    综合应用案例

    归档文件

    实际生产应用中,往往需要对重要数据进行归档备份。

    需求:实现一个每天对指定目录归档备份的脚本,输入一个目录名称(末尾不带/), 将目录下所有文件按天归档保存,并将归档日期附加在归档文件名上,放在/root/archive 下。

    这里用到了归档命令:tar

    后面可以加上-c 选项表示归档,加上-z 选项表示同时进行压缩,得到的文件后缀名 为.tar.gz。

    #!/bin/bash
    # 首先判断输入参数个数是否为 1
    if [ $# -ne 1 ]
    then
    echo "参数个数错误!应该输入一个参数,作为归档目录名"
    exit
    fi
    # 从参数中获取目录名称
    # 判断目录是否存在
    if [ -d $1 ]
    then
    echo
    else
    echo
    echo "目录不存在!"
    echo
    exit
    fi
    DIR_NAME=$(basename $1)
    DIR_PATH=$(cd $(dirname $1); pwd)
    # 获取当前日期
    DATE=$(date +%y%m%d)
    # 定义生成的归档文件名称
    FILE=archive_${DIR_NAME}_$DATE.tar.gz
    DEST=/root/archive/$FILE
    # 开始归档目录文件
    echo "开始归档..."
    echo
    tar -czf $DEST $DIR_PATH/$DIR_NAME
    if [ $? -eq 0 ]
    then
    echo
    echo "归档成功!"
    echo "归档文件为:$DEST"
    echo
    else
    echo "归档出现问题!"
    echo
    fi
    exit
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    发送消息

    我们可以利用 Linux 自带的 mesg 和 write 工具,向其它用户发送消息

    需求:实现一个向某个用户快速发送消息的脚本,输入用户名作为第一个参数,后面直接跟要发送的消息。脚本需要检测用户是否登录在系统中、是否打开消息功能,以及当前发送消息是否为空。

    #!/bin/bash
    login_user=$(who | grep -i -m 1 $1 | awk '{print $1}')
    # [ -z $变量] :判断变量是否为空
    if [ -z $login_user ]
    then
    echo "$1 不在线!"
    echo "脚本退出.."
    exit
    fi
    is_allowed=$(who -T | grep -i -m 1 $1 | awk '{print $2}')
    # 查看用户是否开启消息功能
    # 判is_allowed是否为+
    if [ $is_allowed != "+" ]
    then
    echo "$1 没有开启消息功能"
    echo "脚本退出.."
    exit
    fi
    # 确认有消息发送
    if [ -z $2 ]
    then
    echo "没有消息发出"
    echo "脚本退出.."
    exit
    fi
    # 从参数中获取要发送的消息
    whole_msg=$(echo $* | cut -d " " -f 2- )
    # 获取用户登录的终端
    user_terminal=$(who | grep -i -m 1 $1 | awk '{print $2}')
    # 写入要发送的数据
    echo $whole_msg | write $login_user $user_terminal
    # 确认发送结果
    if [ $? != 0 ]
    then
    echo "发送失败!"
    else
    echo "发送成功!"
    fi
    exit
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
  • 相关阅读:
    设计模式学习笔记(十四)责任链模式实现及在Filter中的应用
    【路径遍历漏洞】查找、利用、预防
    Java:Java中的堆栈和堆内存
    运动“双十一”持续走热,缤跃酒店洞察市场需求,创新打造运动健康酒店!
    认识NR(零):MIMO-OFDM中的信道关系
    WPF 稳定的全屏化窗口方法
    Axure网上超市用户端APP原型 (O2O生鲜电商/买菜到家/数字零售/京东到家/抖音超市领域)
    在Jupyter Notebook中更新模块不丢失变量的方法:使用importlib.reload
    网课搜题公众号 接口查题 查课接口 网课答案题库对接教程
    Think PHP 完整的带富文本格式以及图片上传,并且在页面上分页展示
  • 原文地址:https://blog.csdn.net/pipihan21/article/details/132592944