shell 脚本

流程控制

  • 注意:
  1. 流程控制中的条件判断是具有一定格式的: [ command(中间要用空格分隔) ],如[ a == b ],注意[ command间是有空格的,] 也一样;
  2. 还有一种简便的方法: (())代替[],使用(())对中间没有什么要求的,更加简便,如:if (( a > b )) && (( a < c )) 等价于 if [ $a -gt $b -a $a -lt $c ]
  • if 控制流

    if [ command ]
    then
       符合该条件执行的语句
    elif [ command ]
    then
       符合该条件执行的语句
    else
       符合该条件执行的语句
    fi
    # [ command ] :
    : '
    文件/文件夹(目录)判断:
    [ -b FILE ] 如果 FILE 存在且是一个块特殊文件则为真。
    [ -c FILE ] 如果 FILE 存在且是一个字特殊文件则为真。
    [ -d DIR ] 如果 FILE 存在且是一个目录则为真。
    [ -e FILE ] 如果 FILE 存在则为真。
    [ -f FILE ] 如果 FILE 存在且是一个普通文件则为真。
    [ -g FILE ] 如果 FILE 存在且已经设置了SGID则为真。
    [ -k FILE ] 如果 FILE 存在且已经设置了粘制位则为真。
    [ -p FILE ] 如果 FILE 存在且是一个名字管道(F如果O)则为真。
    [ -r FILE ] 如果 FILE 存在且是可读的则为真。
    [ -s FILE ] 如果 FILE 存在且大小不为0则为真。
    [ -t FD ] 如果文件描述符 FD 打开且指向一个终端则为真。
    [ -u FILE ] 如果 FILE 存在且设置了SUID (set user ID)则为真。
    [ -w FILE ] 如果 FILE存在且是可写的则为真。
    [ -x FILE ] 如果 FILE 存在且是可执行的则为真。
    [ -O FILE ] 如果 FILE 存在且属有效用户ID则为真。
    [ -G FILE ] 如果 FILE 存在且属有效用户组则为真。
    [ -L FILE ] 如果 FILE 存在且是一个符号连接则为真。
    [ -N FILE ] 如果 FILE 存在 and has been mod如果ied since it was last read则为真。
    [ -S FILE ] 如果 FILE 存在且是一个套接字则为真。
    [ FILE1 -nt FILE2 ] 如果 FILE1 has been changed more recently than FILE2, or 如果 FILE1 exists and FILE2 does not则为真。
    [ FILE1 -ot FILE2 ] 如果 FILE1 比 FILE2 要老, 或者 FILE2 存在且 FILE1 不存在则为真。
    [ FILE1 -ef FILE2 ] 如果 FILE1 和 FILE2 指向相同的设备和节点号则为真。
    
    字符串判断:
    [ -z STRING ] 如果STRING的长度为零则为真 ,即判断是否为空,空即是真;
    [ -n STRING ] 如果STRING的长度非零则为真 ,即判断是否为非空,非空即是真;
    [ STRING1 = STRING2 ] 如果两个字符串相同则为真 ;
    [ STRING1 != STRING2 ] 如果字符串不相同则为真 ;
    [ STRING1 ]  如果字符串不为空则为真,与-n类似
    
    数值判断:
    INT1 -eq INT2           INT1和INT2两数相等为真 ,==
    INT1 -ne INT2           INT1和INT2两数不等为真 ,!=
    INT1 -gt INT2            INT1大于INT1为真 ,>
    INT1 -ge INT2           INT1大于等于INT2为真,>=
    INT1 -lt INT2             INT1小于INT2为真 ,<
    INT1 -le INT2             INT1小于等于INT2为真,<=
    
    复杂逻辑判断:
    -a 与
    -o 或
    ! 非
    '
    

    https://blog.csdn.net/zhan570556752/article/details/80399154

  • while 控制流
    例子:

    # 读取文件
    while read line
    do
    	echo $line
    done < filename	
    
    # 打印内核调试信息
    while true;do dmesg -c;done # 脚本中可以使用 ; 代替 \n
    

    shell脚本读取文件的三种方法
    Shell 流程控制

语法

  • 特殊字符
    $n: 传入参数,n为数字,从0开始,0表示脚本的名字
    $#: 传入参数个数,不包括脚本名字
    $$: 当前进程的IP
    $!: 最后运行后台的进程IP
    $?: 最后运行的命令的结束代码(返回值)
    例子:ls;while [ $? == 0 ];do clear;ls ;done #一直打印ls信息直到失败

    Shell 传递参数
    shell中各种参数的说明

  • 注释

  1. 单行注释:#
  2. 块注释:
    #方法1
    : '  注意冒号与引号间有空格
    ...
    '
    
    #方法2
    :<<!
    ...
    !
    
    #方法3
    if false
    then
    	...
    fi
    
  • 字符串操作
  1. 字符串替换:
    只替换第一个子串:${变量名/old/new}
    替换所有子串:${变量名//old/new}
    注:old,new包含需要转义的符号,要加转义符\

  2. 字符串裁剪:
    从左侧开始删除字符串中第一个关键词:${变量名#关键词},加多一个#表示贪婪匹配
    从右侧开始删除字符串中第一个关键词:${变量名%关键词},加多一个%表示贪婪匹配
    如:

    root:~$ echo $test
    rootabcefg
    # 替换
    root:~$ echo ${test/o/1}
    r1otabcefg
    root:~$ echo ${test//o/1}
    r11tabcefg
    # 裁剪
    root:~$ echo ${test#*o}
    otabcefg
    root:~$ echo ${test##*o}
    tabcefg
    root:~$ echo ${test%o*}
    ro
    root:~$ echo ${test%%o*}
    r
    

    https://blog.csdn.net/ldxy22/article/details/107594353

linux 命令

  • 打印:echo
    输出转义字符:-e
    # 不加 -e
    root:~$ echo "[network]\ngenerateResolvConf=ture"
    [network]\ngenerateResolvConf=ture	
    # 加 -e
    root:~$ echo -e "[network]\ngenerateResolvConf=ture"
    [network]
    generateResolvConf=ture
    
  • 查看时磁盘
  1. df -hl : 查看磁盘剩余空间
  2. df -h: 查看各个根路径的分区大小
  3. du -sh: 查看当前目录的大小
  4. du filename: 查看文件的大小
    --max-depth=num:控制查询的目录的深度

    http://c.biancheng.net/linux/du.html

  1. 显示文件最后10行(默认10行): tail xxx1.txt

  2. 显示文件最后3行: tail -n 3 xxx1.txt

  3. 显示文件除了前三行的所有行: tail -n +3 xxx1.txt

  4. 显示文件最后3个字节: tail -c 3 xxx1.txt

  5. 显示文件除了前3个字节的所有字节: tail -c +3 xxx1.txt

  6. 不显示文件名(默认就不显示): tail -q xxx1.txt

  7. 显示文件名: tail -v xxx1.txt

  8. 显示多个文件的后5行内容: tail -n 5 xxx1.txt xxx2.txt

  9. 实时监控文件最后5行内容: tail -f -n 5 xxx1.txt

  10. 每隔3秒更新文件最后5行的内容: tail -f -s 3 -n 5 xxx1.txt

  11. 某个pid为$(PID)的进程结束后,停止刷新文件内容: tail -f --pid $(PID) -n 3 xxx1.txt

    https://blog.csdn.net/sjwangjinbao/article/details/118229660

  • tr:字符替换
    语法:tr [options] [set1] [set2]
    说明: 将输入信息中的set1中的字符替换为set2中的字符
    例如:

    # 将a->1,b->2,c->3
    tr "abc" "123"
    # 将a->1,b->2
    tr "ab" "123"
    # 将a->1,b->2,c->3,d->3
    tr "abcd" "123"
    

    https://www.cnblogs.com/f-ck-need-u/p/7521506.html

  • grep:正则表达式匹配输出

    语法格式:
    grep [options] PATTERN [FILE...]
    grep [options] [-e PATTERN | -f FILE] [FILE...]
    
    匹配模式选择:
     -E, --extended-regexp     扩展正则表达式egrep
     -F, --fixed-strings       一个换行符分隔的字符串的集合fgrep
     -G, --basic-regexp        基本正则
     -P, --perl-regexp         调用的perl正则
     -e, --regexp=PATTERN      后面根正则模式,默认无
     -f, --file=FILE           从文件中获得匹配模式
     -i, --ignore-case         不区分大小写
     -w, --word-regexp         匹配整个单词
     -x, --line-regexp         匹配整行
     -z, --null-data           一个 0 字节的数据行,但不是空行
    
    杂项:
     -s, --no-messages         不显示错误信息
     -v, --invert-match        显示不匹配的行
     -V, --version             显示版本号
     --help                    显示帮助信息
     --mmap                use memory-mapped input if possible
    
    输入控制:
     -m, --max-count=NUM       匹配的最大数
     -b, --byte-offset         打印匹配行前面打印该行所在的块号码。
     -n, --line-number         显示的加上匹配所在的行号
     --line-buffered           刷新输出每一行
     -H, --with-filename       当搜索多个文件时,显示匹配文件名前缀
     -h, --no-filename         当搜索多个文件时,不显示匹配文件名前缀
     --label=LABEL            print LABEL as filename for standard input
     -o, --only-matching       只显示一行中匹配PATTERN 的部分
     -q, --quiet, --silent      不显示任何东西
     --binary-files=TYPE   假定二进制文件的TYPE 类型;
                                          TYPE 可以是`binary', `text', 或`without-match'
     -a, --text                匹配二进制的东西
     -I                        不匹配二进制的东西
     -d, --directories=ACTION  目录操作,读取,递归,跳过
     -D, --devices=ACTION      设置对设备,FIFO,管道的操作,读取,跳过
     -R, -r, --recursive       递归调用
     --include=PATTERN     只查找匹配FILE_PATTERN 的文件
     --exclude=PATTERN     跳过匹配FILE_PATTERN 的文件和目录
     --exclude-from=FILE   跳过所有除FILE 以外的文件
     -L, --files-without-match 匹配多个文件时,显示不匹配的文件名
     -l, --files-with-matches  匹配多个文件时,显示匹配的文件名
     -c, --count               显示匹配的行数
     -Z, --null                在FILE 文件最后打印空字符
    
    文件控制:
     -B, --before-context=NUM  打印匹配本身以及前面的几个行由NUM控制
     -A, --after-context=NUM   打印匹配本身以及随后的几个行由NUM控制
     -C, --context=NUM         打印匹配本身以及随后,前面的几个行由NUM控制
     -NUM                      根-C的用法一样的
     --color[=WHEN],
     --colour[=WHEN]       使用标志高亮匹配字串;
     
     -U, --binary               使用标志高亮匹配字串;
     -u, --unix-byte-offsets   当CR 字符不存在,报告字节偏移(MSDOS 模式)
    

    https://blog.csdn.net/weixin_43658009/article/details/101715130

    正则表达式规则

    ^  #锚定行的开始 如:'^grep'匹配所有以grep开头的行。    
    $  #锚定行的结束 如:'grep$'匹配所有以grep结尾的行。    
    .  #匹配一个非换行符的字符 如:'gr.p'匹配gr后接一个任意字符,然后是p。    
    *  #匹配零个或多个先前字符 如:'*grep'匹配所有一个或多个空格后紧跟grep的行。    
    .*   #一起用代表任意字符。   
    []   #匹配一个指定范围内的字符,如'[Gg]rep'匹配Grep和grep。    
    [^]  #匹配一个不在指定范围内的字符,如:'[^A-FH-Z]rep'匹配不包含A-R和T-Z的一个字母开头,紧跟rep的行。    
    \(..\)  #标记匹配字符,如'\(love\)',love被标记为1。    
    \<      #锚定单词的开始,如:'\<grep'匹配包含以grep开头的单词的行。    
    \>      #锚定单词的结束,如'grep\>'匹配包含以grep结尾的单词的行。    
    x\{m\}  #重复字符x,m次,如:'0\{5\}'匹配包含5个o的行。    
    x\{m,\}  #重复字符x,至少m次,如:'o\{5,\}'匹配至少有5个o的行。    
    x\{m,n\}  #重复字符x,至少m次,不多于n次,如:'o\{5,10\}'匹配5--10个o的行。   
    \w    #匹配文字和数字字符,也就是[A-Za-z0-9],如:'G\w*p'匹配以G后跟零个或多个文字或数字字符,然后是p。   
    \W    #\w的反置形式,匹配一个或多个非单词字符,如点号句号等。   
    \b    #单词锁定符,如: '\bgrep\b'只匹配grep。 
    

    以下正则表达式grep不支持:
    (?=string1)string2:从匹配string1的位置(包括string1,即string1的起始位置)开始匹配string2,如:abcde -> (?=cd)c -> c
    (?<=string1)string2:从匹配到string1的末尾位置(即string1的末尾位置)开始匹配string2,如:abcde -> (?<=cd)e -> e
    (?!string1)string2:从不匹配string1的位置(包括string1,即string1的起始位置)开始匹配string2,如:abcde -> (?=cd)c -> c
    (?<!string1)string2:从不匹配到string1的末尾位置(即string1的末尾位置)开始匹配string2,如:abcde -> (?<!cd)a -> a
    注意:这些都是代表一个位置不是字符,和^,$类似
    例子:

    #匹配 vmx 字符串, 要加""
    cat /proc/cpuinfo | grep "\(vmx\)"
    

    正则表达式在线测试:https://c.runoob.com/front-end/854/?optionGlobl=global

    https://blog.csdn.net/qq_45463524/article/details/114279726

注意

  1. 保证调试执行时使用的shell要一致,即#!/bin/bash 和 默认的shell一致

    https://www.cnblogs.com/fenglongyu/p/7450781.html

  2. 2>1、2>&1 区别

    2 > 1 # 将stderr 重定向为 文件 1
    2 >&1 # 将stderr 重定向为 文件描述符为1的文件(stdout)
    

    https://blog.csdn.net/chungong2808/article/details/100820272

  3. 1>/dev/null 2>&1

    /dev/null # 只能输入,重定向到这就是不输出
    1>/dev/null 2>&1 # 表示不输出
    

    https://www.cnblogs.com/tinywan/p/6025468.html

  4. /dev/zero:输出都为0

  5. shell中要使用命令处理一个变量,变量是带有空格的字符串,可以引用时加""反正把空格当作分隔符

    root:~$ test="test 123"
    # 不加""
    root:~$ cat $test
    cat: test: No such file or directory
    cat: 123: No such file or directory
    # 加""
    root:~$ cat "$test"
    cat: 'test 123': No such file or directory
    

实用的shell例子

https://zhuanlan.zhihu.com/p/382378977

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值