掌握shell脚本编程 进阶Linux高手

shell 基础

自定义变量

变量名遵循原则

  • 变量是任何字母、数字和下划线组成的字符串,且不能以数字开头

  • 区分字母大小写,例如 Var1 和 var1 是不同的

  • 变量、等号、值中间不能出现任何空格

变量引用

  • var1=10 等号前后不能有空格

  • echo $var1

#!/bin/bash

var1=abc

echo $var1

位置变量

当一个命令或者脚本执行的是哦户,后面可以跟多个参数,我们使用位置参数变量来表示这些参数

位置参数变量含义
$nn 为数字,$0 代表脚本本身,$1~9代表1−9个参数,10以上的参数需要大括号包含,如9代表1−9个参数,10以上的参数需要大括号包含,如{10}
$@命令行所有参数,但是每个参数区别对待
$*命令行所有参数,所有参数视为一个整体
$#参数的个数

环境变量

简介

  • linux 是一个多租户的操作系统,针对不同的用户都会有一个转悠的运行环境

  • 不同用户的专有环境就是一组默认环境变量的组合

环境变量的分类

  • 对所有用户生效的环境变量 /ect/profile

  • 对特定用户的生效的环境变量 ~/.bashrc 或者 ~/.bash_profile

  • 练市有效的环境变量 脚本或者命令行使用 export

常用的环境变量

环境变量含义
PATH命令搜索的路径
HOME用户的家目录的路径
LOGNAME用户登录名
PWD当前所在的路径
HISTFILE历史命令的保存文件
HISTSIZE历史命令保存的最大行数
HOSTNAME主机名
SHELL用户当前使用的 SHELL
PS1以及命令提示符
TMOUT用户和系统交互过程的超时值
IFS系统输入的分隔符
OFS系统输出的分隔符

环境变量一般都是大写​

管道

  • 将系统上所有的软件包列出来,然后去搜索 Python 相关的软件包

  • 解决方法:使用命令列出系统已有的所有软件包,然后把结果重定向到文件中,然后在文件中搜索 python

  • rpm -qa > all_soft.txt 在利用 vim 去搜索 python

使用管道解决问题

  • 列出所有的软件包,然后将结果传递给后续命令处理

  • rpm -qa | grep python | wc -l

管道定义

  • 将一个命令的输出作为另一个命令的输入

  • 从某种意义上来说,是重定向的简易实现

退出状态码

  • 所有的 shell 命令都使用退出状态码来告知 shell 它已经执行完毕

  • 退出状态码是一个 0~255 的整数值

  • Linux 提供了一个$?来捕获退出状态码的值

image.png

实践用法

状态码含义
0命令执行成功的情况
非 0不成功的情况

改变退出状态码 exit 命令

  • 退出状态码是以上一条指令的返回结果为准

  • exit $exit_code

  • exit 48 或者 exit 125 或者 exit 0

单引号和双引号有哪些坑

  • 处理变量时,单引号和双引号的区别

  • 处理字符串变量时,单引号和双引号的区别

  • 单引号套用是需要注意那些区别

  • sed 和 awk 中需要注意单双引号的那些差异

判断和控制

使用 if-then 语句

if command | condition
then
    commands
fi
if command | condition
then
    commands
else
    commands
fi

嵌套 if

if command | condition
then
    commands
elif command | condition
    commands
else
    commands
fi

条件测试 - 数值比较

image.png

  • 需要使用方括号包裹条件

  • command 返回 0, 执行 if 中的语句

  • condition true 执行 if 中的语句

image.png

字符串比较

image.png

文件比较

image.png

image.png

复合条件

var1=56
var2=23
var3=89

if [ $var1 -gt $var2 ] && [ $var3 -lt $var3 ];then
    echo "$var1 < $var2 并且 $var2 > $var3"
fi

if-then 中使用双括号

  • 使用双括号进行算数运算
if (( expression )); then
    command
fi

image.png

image.png

  • 双括结构中,变量名引用可以加$,也可以不加

  • 运算符前后可以有空格,也可以没有

  • 可以用于 if、for、while 等循环控制结构中

  • 多个运算符使用逗号分割

双方括号

  • 双括号结构中,变量名引用必须加$

  • 双方括号]]前面必须有空格,[[后面也必须有空格

case 命令

case $var in
    pattern1)
      commands
    ;;
  pattern2)
      commands
    ;;
  *)
      commands
    ;;
esac

for 命令

for vat in list
do
    commands
done

for 读取列表值

for i in Beijing Shanghai Nanjing
do
    echo ''
done

for i in {1..20}
do
    echo "number is $i"
done

for 循环读取变量的值

IFS=":"

list="Zhangsan Lisi Mike"
for i in $list
do
    echo "number is $i"
done

for 循环从命令执行结果读取值

# 命令替换
for i in $(ls /opt)
do
    echo 'all list'
done

c 语言风格的 for 循环

for (( i=10; i < 50; i++ ))
do
    echo 'current'
done

while 循环命令

while command
do
    commands
done

until 命令

until command
do
    echo "number is $1"
done

控制循环的 break 指令

break n 退出深层的循环​

处理 for 循环的输出

可以使用重定向和管道输出来对 for 循环的结果进行处理。

变量的高级用法

变量的替换

image.png

image.png

变量的测试

image.png

字符串处理

计算字符串长度

image.png

获取子串在字符串中的索引位置

image.png

获取子串的长度

image.png

抽取子串

image.png

字符串处理完整的脚本

image.png

命令替换

  • command

  • $(command)

有类型的变量

  • declare 命令和 typeset 命令两者等价

  • declare、typeset 命令都是用来定义变量类型的

image.png

declare -a ("a" "b")

  • +a取消

  • -a设置

bash 数学运算 expr

  • expr $num1 operator $num2

  • $(($num1 operator $num2))

image.png

image.png

bash 数学运算之 bc

  • bc 是 bash 内建的运算器,支持浮点数运算

  • 内建变量 scale 可以设置,默认为 0

image.png

image.png

echo "24/7" | bc

函数的高级用法

函数的定义和使用

  • Linux Shell 中的函数和大多数编程语言中的函数一样

  • 将相似的任务或者代码封装到函数中,供其他地方调用

第一种格式

name()
{
    command
}

第二种格式

function name
{
    command
}
  • 直接使用函数名调用,可以将其想象成 shell 中的一条命令

  • 函数内部可以直接使用参数$1,$2$n

  • 函数调用: function_name $1 $2

ps -ef | grep nginx | grep -v grep

向函数传递参数

function name
{
    echo "Hello $1"
}

函数的返回值

使用 return 返回值

  • 使用 return 返回值只能返回 1-255 的整数

  • 函数使用 return 返回值,通常只是用来供其他地方调用获取状态,因此通常仅返回 0 或 1;0 表示成功,1 表示失败

使用 echo 返回值

  • 使用 echo 可以返回任何字符串结果

  • 通常用于返回数据,比如一个字符串值或者列表值

全部变量和局部变量

全局变量

  • 不做特殊生命,shell 中变量都是全局变量

  • Tips 大型脚本程序中函数慎用全局变量

局部变量

  • 定义变量时,使用 local 关键字

  • 函数内和外若存在同名的变量,则函数内部变量覆盖外部变量

函数库

为什么要定义函数库

  • 经常使用的重读代码封装成函数文件

  • 一般不直接执行,而是通过其他脚本调用

经验之谈

  • 库文件名的后缀是任意的,但一般使用.lib

  • 库文件通常没有可执行的权限的

  • 库文件无需和脚本在拥挤目录,秩序在脚本引用时指定

  • 第一行一般使用#!/bin/echo, 输出警告信息,避免用户执行

Shell 编程中的常用工具

文件查找 find 命令

find 命令语法格式 find [路径] [选项] [操作]

选项参数对照表

image.png

image.png

find命令总结:

    常用选项:

        -name            查找/etc目录下以conf结尾的文件    find /etc -name '*conf'
        -iname            查找当前目录下文件名为aa的文件,不区分大小写    find . -iname aa
        -user            查找文件属主为hdfs的所有文件    find . -user hdfs
        -group            查找文件属组为yarn的所有文件    find . -group yarn
        -type

            f        文件                find . -type f
            d        目录                find . -type d
            c        字符设备文件        find . -type c
            b        块设备文件            find . -type b
            l        链接文件            find . -type l
            p        管道文件            find . -type p


        -size

            -n        小于大小n的文件
            +n        大于小于n的文件

            例子1:查找/etc目录下小于10000字节的文件        find /etc -size -10000c
            例子2:查找/etc目录下大于1M的文件                find /etc -size +1M

        -mtime

            -n        n天以内修改的文件
            +n        n天以外修改的文件
            n        正好n天修改的文件

            例子1:查找/etc目录下5天之内修改且以conf结尾的文件    find /etc -mtime -5 -name '*.conf'
            例子2:查找/etc目录下10天之前修改且属主为root的文件    find /etc -mtime +10 -user root

        -mmin

            -n        n分钟以内修改的文件
            +n        n分钟以外修改的文件

            例子1:查找/etc目录下30分钟之前修改的文件        find /etc -mmin +30
            例子2:查找/etc目录下30分钟之内修改的目录        find /etc -mmin -30 -type d

        -mindepth n        表示从n级子目录开始搜索

            例子:在/etc下的3级子目录开始搜索        find /etc -mindepth 3

        -maxdepth n        表示最多搜索到n级子目录

            例子1:在/etc下搜索符合条件的文件,但最多搜索到2级子目录        find /etc -maxdepth 3 -name '*.conf'
            例子2:
                find ./etc/ -type f -name '*.conf' -size +10k -maxdepth 2




    了解选项:

        -nouser        查找没有属主的用户

            例子:find . -type f -nouser

        -nogroup    查找没有属组的用户

            例子:find . -type f -nogroup

        -perm

            例子:find . -perm 664

        -prune

            通常和-path一起使用,用于将特定目录排除在搜索条件之外
            例子1:查找当前目录下所有普通文件,但排除test目录
                find . -path ./etc -prune -o -type f
            例子2:查找当前目录下所有普通文件,但排除etc和opt目录
                find . -path ./etc -prune -o -path ./opt -prune -o -type f
            例子3:查找当前目录下所有普通文件,但排除etc和opt目录,但属主为hdfs
                find . -path ./etc -prune -o -path ./opt -prune -o -type f -a -user hdfs
            例子4:查找当前目录下所有普通文件,但排除etc和opt目录,但属主为hdfs,且文件大小必须大于500字节
                find . -path ./etc -prune -o -path ./opt -prune -o -type f -a -user hdfs -a -size +500c

        -newer file1

            例子:find /etc -newer a

    操作:


        -print        打印输出

        -exec        对搜索到的文件执行特定的操作,格式为-exec 'command' {} \;

            例子1:搜索/etc下的文件(非目录),文件名以conf结尾,且大于10k,然后将其删除

                find ./etc/ -type f -name '*.conf' -size +10k -exec rm -f {} \;

            例子2:将/var/log/目录下以log结尾的文件,且更改时间在7天以上的删除

                find /var/log/ -name '*.log' -mtime +7 -exec rm -rf {} \;

            例子3:搜索条件和例子1一样,只是不删除,而是将其复制到/root/conf目录下

                find ./etc/ -size +10k -type f -name '*.conf' -exec cp {} /root/conf/ \;

        -ok            和exec功能一样,只是每次操作都会给用户提示

    逻辑运算符:

        -a            与
        -o            或
        -not|!        非

        例子1:查找当前目录下,属主不是hdfs的所有文件

            find . -not -user hdfs     |    find . ! -user hdfs

        例子2:查找当前目录下,属主属于hdfs,且大小大于300字节的文件

            find . -type f -a -user hdfs -a -size +300c

        例子3:查找当前目录下的属主为hdfs或者以xml结尾的普通文件

            find . -type f -a \( -user hdfs -o -name '*.xml' \)

常用的查找命令

find、locate、whereis 和 which 总结及使用场景分析​

locate 命令介绍

  • 文件查找命令,所属软件包 mlocate

  • 不同于 find 命令是在整块磁盘中搜索,locate 命令是在数据库文件中查找

  • find 是默认全部匹配,locate 则是默认部分匹配

updatedb 命令

  • 用户更新/var/lib/mlocate/mlocate.db

  • 所使用配置文件/etc/updatedb.conf

  • 改命令在后台 cron 计划中定期执行

whereis 命令

  • 作用:查找某个命令的二进制程序文件、帮助文档、源代码文件

image.png

which 命令

  • 作用:今查找二进制文件

image.png

各个命令使用场景的推荐

命令适用场景优缺点
find查找某一类文件,比如文件名部分一致功能强大,速度慢
locate只能查找单个文件功能单一,速度快
whereis查找程序的可执行文件、帮助文档不常用
which只查找程序的可执行文件常用语查找程序的绝对路径

grep 和 egrep

  1. grep [option] [pattern] [file1,file2...]

  2. command | grep [option] [pattern]

image.png

不常用

image.png

sed

sed (stream editor),流编辑器。对标准输出或文件逐行进行处理​

语法格式

  • stdout | sed [option] "pattern command"

  • sed [option] "pattern command" file

sed 选项

image.png

sed 中 pattern 详解

image.png

sed 中的编辑命令详解

类别编辑命令含义
查询p打印
新增a行后追加
i行前追加
r外部文件读入,行后追加
w匹配行写入外部文件
删除d删除
修改s/old/new将行内第一个 old 换成 new
s/old/new/g将行内全部 old 更换为 new
s/old/new/2将行内前两个 old 更换成 new
s/old/new/ig将行内的 old 全部更换为 new,忽略大小写

&\1 都可以代表反向引用,\1需要将前面匹配到的区域用括号括起来​

利用 sed 删除特定的内容

image.png

利用 sed 修改文件内容

image.png

awk

简介:awk 是一个文本处理工具,通常用于处理数据并生成结果报告

awk 的工作模式

image.png

语法格式:

  • awk 'BEGIN{}parrern{commands}END{}' file_name

  • standard output | awk 'BEGIN{}parttern{commands}END{}'

image.png

awk 的内置变量

image.png

image.png

awk 的格式化输出

image.png

image.png

awk 模式匹配的两种用法

  • RegExp

  • 关系运算符匹配

image.png

image.png

awk 动作表达式中的算数运算符

image.png

awk 中条件语句

image.png

image.png

awk 中的字符串函数

image.png

image.png

awk 选项总结

image.png

awk 中数组中的用法

shell 中数组的用法

image.png

image.png

曹儒士子 AI 爱好者,正在探索智能世界的无限可能。

订阅通讯

新文章直达你的收件箱。