第三周

第三周

欲练此功,必先自宫

shell

创建shell脚本

  • 第一步:使用文本编辑器来创建文本文件
  • 第一行必须包括shell声明序列:#!
       示例:#!/bin/bash
  • 添加注释:  注释以#开头
  • 第二步:运行脚本
      给予执行权限,在命令行上指定脚本的绝对或相对路径
      直接运行解释器,将脚本作为解释器程序的参数运行
脚本规范

1.第一行一般为调用使用的语言
2.程序名,避免更改文件名为无法找正确的文件
3.版本号
4.更改后的时间
5.作者相关信息
6.该程序的作用,及注意事项
7最后是各版本版本的更新简要说明

编写⽣成脚本基本格式的脚本,包括作者,联系⽅式,版本,时间,描述等
set ignorecase
set cursorline
set autoindent
autocmd BufNewFile *.sh exec ":call SetTitle()"
func SetTitle()
        if expand("%:e") == 'sh'
        call setline(1,"#!/bin/bash")
        call setline(2,"#")
        call setline(3,"#****************************************************")                                                     
        call setline(4,"#Author:                wlp     ")
        call setline(5,"#QQ:                    449099995")
        call setline(6,"#Date:                  ".strftime("%Y-%m-%d"))
        call setline(7,"#FileName:             ".expand("%"))
        call setline(8,"#URL:                     ")
        call setline(9,"#Description:          The test script") 
        call setline(10,"#Copyright (C):        ".strftime("%Y")." All rights reserved")
        call setline(11,"#***************************************************") 
        call setline(12,"") 
        endif
endfunc
autocmd BufNewFile * normal G 

脚本中的变量

Shell中变量命名法则:
  • 1、不能使程序中的保留字:例如if, for
  • 2、只能使用数字、字母及下划线,且不能以数字开头
  • 3、见名知义
  • 4、统一命名规则:驼峰命名法
Shell中命名建议规则:
  • 1、变量名大写
  • 2、局部变量小写
  • 3、函数名小写
  • 4、用英文名字,并体现出实际作用
局部变量

变量赋值:name=‘value’
可以使用引用value

  • (1) 可以是直接字串:name=“root"
  • (2) 变量引用:name="$USER"
  • (3) 命令引用:name=COMMAND
           name=$(COMMAND)

变量引用:${name} 或者 $name

  • " " 弱引用,其中的变量引用会被替换为变量值
  • ’ ’ 强引用,其中的变量引用不会被替换为变量值,而保持原字符串
    显示已定义的所有变量:set

删除变量:unset name

单引号、双引号、反向单引号区别:
  • 1、由单引号(’),强引用,其中的变量会被替换未变量值。
  • 2、由双引号("),弱引用,其中的变量不会被替换未变量值,而保持原字符串。
  • 3、反向单引号(`)括起来的字符串被shell解释为命令行,在执行时,shell首先执行该命令行,并以它的标准 输出结果取代整个反引号(包括两个反引号)部分。
环境变量

变量声明、赋值:

  • export name=VALUE
  • declare -x name=VALUE

变量引用: $name, ${name}
显示所有环境变量:env printenv  export declare -x
删除变量: unset name

只读变量:

只读变量:只能声明,但不能修改和删除
声明只读变量:

  • readonly name
  • declare -r name
    查看只读变量:
  •  readonly -
    
位置变量:

位置变量:在脚本代码中调用通过命令行传递给脚本的参数

  • $1, $2, … 对应第1、第2等参数,shift [n]换位置
  • $0 命令本身
  • $* 传递给脚本的所有参数,全部参数合为一个字符串
  • $@ 传递给脚本的所有参数,每个参数为独立字符串
  • KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲ 传递给脚本的参数的个数 …@ $* 只在被双引号包起来的时候才会有差异
  • set – 清空所有位置变
退出状态:

进程使用退出状态来报告成功或失败0 代表成功,1-255代表失败$? 变量保存近的命令退出状态

bash自定义退出状态码
exit [n]:自定义退出状态码

算术运算:

bash中的算术运算:help let

  • +, -, *, /, %取模(取余), **(乘方),乘法符号有些场景中需要转义

实现算术运算:

  • (1) let var=算术表达式
  • (2) var=$[算术表达式]
  • (3) var=$((算术表达式))
  • (4) var=$(expr arg1 arg2 arg3 …)
  • (5) declare –i var = 数值
  • (6) echo ‘算术表达式’ | bc

bash有内建的随机数生成器变量:$RANDOM(0-32767)

  • 示例:生成 0 - 49 之间随机数
  • echo [ [ [RANDOM%50]
赋值:

增强型赋值:

  • +=, -=, *=, /=, %=

let varOPERvalue

  • 例如:let count+=3
    自加3后自赋值

自增,自减:

  • let var+=1
  • let var++
  • let var-=1
  • let var–
条件测试:

判断某需求是否满足,需要由测试机制来实现。专用的测试表达式需要由测试命令辅助完成测试过程 评估布尔声明,以便用在条件性执行中
若真,则返回0
若假,则返回1

测试命令:

  • test EXPRESSION
  • [ EXPRESSION ]
  • [[ EXPRESSION ]]
  • 注意:EXPRESSION前后必须有空白字符
数值测试:
  • -v VAR
    变量VAR是否设置

数值测试:

  • -gt 是否大于
  • -ge 是否大于等于
  • -eq 是否等于
  • -ne 是否不等于
  • -lt 是否小于
  • -le 是否小于等于
字符串测试
  • = 是否等于
  • ascii码是否大于ascii码

  • < 是否小于
  • != 是否不等于
  • =~ 左侧字符串是否能够被右侧的PATTERN所匹配
  • 注意: 此表达式一般用于[[ ]]中;扩展的正则表达式
  • -z "STRING“ 字符串是否为空,空为真,不空为假
  • -n "STRING“ 字符串是否不空,不空为真,空为假
⽂件存在性和类型测试

存在性测试

  • -a FILE:同-e
  • -e FILE: 文件存在性测试,存在为真,否则为假

存在性及类别测试

  • -b FILE:是否存在且为块设备文件
  • -c FILE:是否存在且为字符设备文件
  • -d FILE:是否存在且为目录文件
  • -f FILE:是否存在且为普通文件
  • -h FILE 或 -L FILE:存在且为符号链接文件
  • -p FILE:是否存在且为命名管道文件
  • -S FILE:是否存在且为套接字文件
⽂件权限测试:
  • -r FILE:是否存在且可读
  • -w FILE: 是否存在且可写
  • -x FILE: 是否存在且可执行
⽂件特殊权限测试
  • -u FILE:是否存在且拥有suid权限
  • -g FILE:是否存在且拥有sgid权限
  • -k FILE:是否存在且拥有sticky权限
⽂件属性测试

文件大小测试:

  • -s FILE: 是否存在且非空

文件是否打开:

  • -t fd: fd 文件描述符是否在某终端已经打开
  • -N FILE:文件自从上一次被读取之后是否被修改过
  • -O FILE:当前有效用户是否为文件属主
  • -G FILE:当前有效用户是否为文件属组

双目测试:

  • FILE1 -ef FILE2: FILE1是否是FILE2的硬链接
  • FILE1 -nt FILE2: FILE1是否新于FILE2(mtime)
  • FILE1 -ot FILE2: FILE1是否旧于FILE2
组合测试

第一种方式:

  • EXPRESSION1 -a EXPRESSION2 并且
  • EXPRESSION1 -o EXPRESSION2 或者
  • ! EXPRESSION
    必须使用测试命令进行,[[ ]] 不支持

第二种方式:

  • COMMAND1 && COMMAND2 并且,短路与,代表条件性的AND THEN
  • COMMAND1 || COMMAND2 或者,短路或,代表条件性的OR ELSE
  • ! COMMAND 非
    如:[ -f “KaTeX parse error: Expected 'EOF', got '&' at position 9: FILE” ] &̲& [[ “FILE”=~ .*.sh$ ]]
read命令:

使用read来把输入值分配给一个或多个shell变量

  • -p 指定要显示的提示
  • -s 静默输入,一般用于密码
  • -n N 指定输入的字符长度N
  • -d ‘字符’ 输入结束符
  • -t N TIMEOUT为N秒
  • read 从标准输入中读取值,给每个单词分配一个变量。所有剩余单词都被分配给后一个变量
  • read -p "Enter a filename: " FILE
[ ]和[[ ]] 的区别

   [ ] 实际上是bash 中 test 命令的简写。即所有的 [ expr ] 等于 test expr。对 test 命令来说, 用 -eq 要进行数字比较,而你此时传入字符串,就报错了。
  [[ expr ]] 是bash中真正的条件判断语句,其语法更符合编程习惯 (比如 &&, || 的用法),虽然我认 为在 [[ ]] 中 故意传字符串给 -eq 也应该像 test 一样报错,但是显然bash实现中直接把非整数的字符串直 接转换成了 0 (你可以自行验证,在 [[ ]] 中的,任何需要整数,但是提供的确又是其他不能转换成整数的字 符串,都变成了0)。 这应该是bash实现中的没有对 [[ ]] 中 -eq 操作符两边的内容进行检查导致的。

判断语句()、 (( ))和{}的区别。

1、单⼩括号 ()

   ①命令组。括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用。括 号中多个命令之间用分号隔开,后一个命令可以没有分号,各命令和括号之间不必有空格。
  ②命令替换。等同于cmd,shell扫描一遍命令行,发现了 ( c m d ) 结 构 , 便 将 (cmd)结构,便将 (cmd)便(cmd)中的cmd执行一次,得到 其标准输出,再将此输出放到原来命令。有些shell不支持,如tcsh。
  ③用于初始化数组。如:array=(a b c d)
2、双⼩括号 (( ))
   ①整数扩展。这种扩展计算是整数型的计算,不支持浮点型。((exp))结构扩展并计算一个算术表达式的值, 如果表达式的结果为0,那么返回的退出状态码为1,或者 是"假",而一个非零值的表达式所返回的退出状态码将 为0,或者是"true"。若是逻辑判断,表达式exp为真则为1,假则为0。
   ②只要括号中的运算符、表达式符合C语言运算规则,都可用在$((exp))中,甚至是三目运算符。作不同进位 (如二进制、八进制、十六进制)运算时,输出结果全都自动转化成了十进制。如:echo $((16#5f)) 结果为95 (16进位转十进制)
  ③单纯用 (( )) 也可重定义变量值,比如 a=5; ((a++)) 可将 KaTeX parse error: Expected 'EOF', got '&' at position 12: a 重定义为6 &̲emsp;&emsp;④常用于…符号前缀。括号内支持多个表达式用逗号分开。 只要括
号中的表达式符合C语言运算规则,比如可以直接使用for((i=0;i<5;i++)), 如果不使用双括号, 则为for i in seq 0 4或者for i in {0…4}。再如可以直接使用if (($i<5)), 如果不使用双括号, 则为if [ $i -lt 5 ]。

  (1)单小括号,(cmd1;cmd2;cmd3) 新开一个子shell顺序执行命令cmd1,cmd2,cmd3, 各命令之间用分号隔开, 后一个命令后可以没有分号。
  (2)单大括号,{ cmd1;cmd2;cmd3;} 在当前shell顺序执行命令cmd1,cmd2,cmd3, 各命令之间用分号隔开, 后一个命令后必须有分号, 第一条命令和左括号之间必须用空格隔开。
3、⼤括号、花括号 {}
  ①大括号拓展。(通配(globbing))将对大括号中的文件名做扩展。在大括号中,不允许有空白,除非这个空白 被引用或转义。第一种:对大括号中的以逗号分割的文件列表进行拓展。如 touch {a,b}.txt 结果为a.txt b.txt。第二种:对大括号中以点点(…)分割的顺序文件列表起拓展作用,如:touch {a…d}.txt 结果为 a.txt b.txt c.txt d.txt
# ls {ex1,ex2}.sh
ex1.sh ex2.sh
# ls {ex{1…3},ex4}.sh
ex1.sh ex2.sh ex3.sh ex4.sh
# ls {ex[1-3],ex4}.sh
ex1.sh ex2.sh ex3.sh ex4.sh

②代码块,又被称为内部组,这个结构事实上创建了一个匿名函数 。与小括号中的命令不同,大括号内的命令 不会新开一个子shell运行,即脚本余下部分仍可使用括号内变量。括号内的命令间用分号隔开,后一个也必须 有分号。{}的第一个命令和左括号之间必须要有一个空格。

建⽴条件脚本

1、条件选择if语句

选择执行:
注意:if语句可嵌套

  • 单分支
    if 判断条件;then
       条件为真的分支代码
    fi
      
  • 双分支
    if 判断条件; then
      条件为真的分支代码
    else
      条件为假的分支代码
    fi
  • 多分支
    if 判断条件1; then
       条件1为真的分支代码
    elif 判断条件2; then
       条件2为真的分支代码
    elif 判断条件3; then
       条件3为真的分支代码
    else
      以上条件都为假的分支代码
    fi
    逐条件进行判断,第一次遇为“真”条件时,执行其分支,而后结束整个if语句
2、条件判断:case语句

case 变量引用 in
PAT1)
  分支1
  ;
PAT2)
  分支2
  ;

*)
esac
case支持glob风格的通配符:
   *:任意长度任意字符
  ?:任意单个字符
   []:指定范围内的任意单个字符
   a|b: a或b

3、bash如何展开命令⾏

把命令行分成单个命令词
展开别名
展开大括号的声明({})
展开波浪符声明(~)
命令替换$() 和 ``)
再次把命令行分成命令词
展开文件通配(*、?、[abc]等等)
准备I/0重导向(<、>)
运行命令

4、防⽌扩展
  • 反斜线(\)会使随后的字符按原意解释
    echo Your cost: $5.00
    Your cost: $5.00
  • 加引号来防止扩展
    • 单引号(’’)防止所有扩展
    • 双引号(”“)也可防止扩展,但是以下情况例外:
    $(美元符号) 变量扩展
    (反引号) 命令替换
    \(反斜线) 禁止单个字符扩展
    !(叹号) 历史命令替换
5、bash的配置⽂件。按⽣效范围划分,存在两类:
  • 全局配置:
    /etc/profile
    /etc/profile.d/*.sh
    /etc/bashrc 个人配置:
    ~/.bash_profile
    ~/.bashrc

  • 修改profile和bashrc文件后需生效
    1重新启动shell进程
    2 . 或source

6、set 命令
  • $- 变量
      h:hashall,打开这个选项后,Shell 会将命令所在的路径hash下来,避免每次都要查询。通过set +h将h 选项关闭
      i:interactive-comments,包含这个选项说明当前的 shell 是一个交互式的shell。所谓的交互式 shell,在脚本中,i选项是关闭的。
      m:monitor,打开监控模式,就可以通过Job control来控制进程的停止、继续,后台或者前台执行等。
      B:braceexpand,大括号扩展
      H:history,H选项打开,可以展开历史列表中的命令,可以通过!感叹号来完成,例如“!!”返回上近的一 个历史命令,“!n”返回第 n 个历史命令

  • set 命令
      -u 在扩展一个没有设置的变量时,显示错误信息,等同set –o nounset
      -e 如果一个命令返回一个非0退出状态值(失败)就退出,等同set –o errexit




find

使用find命令在多条件限定下查找符合条件的文件

指搜索层级

  • -maxdepth level 大搜索目录深度,指定目录为第1级
  • -mindepth level 小搜索目录深度
先处理目录内的文件,再处理目录
  • -depth 根据文件名和inode查找:
  • -name “文件名称”:支持使用glob,*, ?, [], [^]
  • -iname “文件名称”:不区分字母大小写
  • -inum n 按inode号查找
  • -samefile name 相同inode号的文件
  • -links n 链接数为n的文件
  • -regex “PATTERN”:以PATTERN匹配整个文件路径,而非文件名
根据属主、属组查找:
  • -user USERNAME:查找属主为指定用户(UID)的文件
  • -group GRPNAME: 查找属组为指定组(GID)的文件
  • -uid UserID:查找属主为指定的UID号的文件
  • -gid GroupID:查找属组为指定的GID号的文件
  • -nouser:查找没有属主的文件
  • -nogroup:查找没有属组的文件 根据文件类型查找
  • -type TYPE
    • f: 普通文件
    • d: 目录文件
    • l: 符号链接文件
    • s:套接字文件
    • b: 块设备文件
    • c: 字符设备文件
    • p: 管道文件 空文件或目录-empty
    find /app -type d -empty
查找条件

组合条件: 与:-a 或:-o 非:-not !
德·摩根定律:
(非 A) 或 (非 B) = 非(A 且 B)
(非 A) 且 (非 B) = 非(A 或 B)
示例:!A -a !B = !(A -o B) !A -o !B = !(A -a B)

根据⽂件⼤⼩来查找
  • -size [+|-]#UNIT 常用单位:k, M, G,c(byte)
  • #UNIT: (#-1, #] 如:6k 表示(5k,6k]
  • -#UNIT:[0,#-1] 如:-6k 表示[0,5k]
  • +#UNIT:(#,∞) 如:+6k 表示(6k,∞)
以“天”为单位,
  • -atime [+|-]#,
      #: [#,#+1)
      +#: [#+1,∞]
      -#: [0,#)
  • -mtime -ctime
以“分钟”为单位
  • -amin , -mmin , -cmin
根据权限查找:
  • -perm [/|-]MODE
    MODE: 精确权限匹配
    /MODE:任何一类(u,g,o)对象的权限中只要能一位匹配即可,或关系,+ 从centos7开始淘汰
    -MODE:每一类对象都必须同时拥有指定权限,与关系 0 表示不关注
  • find -perm 755 会匹配权限模式恰好是755的文件
  • 只要当任意人有写权限时,find -perm +222就会匹配
  • 只有当每个人都有写权限时,find -perm -222才会匹配
  • 只有当其它人(other)有写权限时,find -perm -002才会匹配

处理动作

  • -print:默认的处理动作,显示至屏幕
  • -ls:类似于对查找到的文件执行“ls -l”命令 -delete:删除查找到的文件
  • -fls file:查找到的所有文件的长格式信息保存至指定文件中
  • -ok COMMAND {} ; 对查找到的每个文件执行由COMMAND指定的命令,对于每个文件执行命令之前,都会交互式 要求用户确认
  • -exec COMMAND {} ; 对查找到的每个文件执行由COMMAND指定的命令
  • {}: 用于引用查找到的文件名称自身 find传递查找到的文件至后面指定的命令时,查找到所有符合条件的文件一次性传递给后面的命令

参数替换xargs

  • 由于很多命令不支持管道|来传递参数,而日常工作中有这个必要,所以就有了xargs命令 xargs用于产生某个命令的参数,xargs 可以读入 stdin 的数据,并且以空格符或回车符将 stdin 的数据分隔 成为arguments
    注意:文件名或者是其他意义的名词内含有空格符的情况
    有些命令不能接受过多参数,命令执行可能会失败,xargs可以解决
    示例:
    ls f* |xargs rm
    find /sbin/ -perm +700 |ls -l 这个命令是错误的
    find /bin/ -perm /7000 | xargs ls -l 查找有特殊权限的文件
    find /bin/ -perm -7000 | xargs ls -l 此命令和上面有何区别?
    find和xargs格式:find | xargs COMMAND

压缩归档打包⽂件

compress/uncompress

compress [-dfvcVr] [-b maxbits] [file …]

  • -d 解压缩,相当于uncompress
  • -c 结果输出至标准输出,不删除原文件
  • -v 显示详情
  • uncompress file.Z 解压缩
  • zcat file.Z 不显式解压缩的前提下查看文本文件内容
    示例:zcat file.Z >file
gzip/gunzip

gzip [OPTION]… FILE …

  • -d 解压缩,相当于gunzip
  • -c 结果输出至标准输出,保留原文件不改变
  • -# 指定压缩比,#取值为1-9,值越大压缩比越大

gunzip file.gz 解压缩
zcat file.gz 不显式解压缩的前提下查看文本文件内容

  • 示例:
    gzip -c messages >messages.gz
    gzip -c -d messages.gz > messages
    zcat messages.gz > messages
    cat messages | gzip > m.gz
bzip2/bunzip2/bzcat
  • -k keep, 保留原文件
  • -d 解压缩
  • -# 1-9,压缩比,默认为9

bunzip2 file.bz2 解压缩 bzcat file.bz2
不显式解压缩的前提下查看文本文件内容

xz/unxz/xzcat
  • 打包压缩 zip –r /backup/sysconfig /etc/sysconfig/
  • 解包解压缩 unzip sysconfig.zip
         cat/var/log/messages | zip messages
         unzip -p message > message
tar⼯具

tar(Tape ARchive,磁带归档的缩写)
tar [OPTION]…

  • (1) 创建归档
    tar -cpvf /PATH/FILE.tar FILE…
  • (2) 追加文件至归档: 注:不支持对压缩文件追加
    tar -r -f /PATH/FILE.tar FILE…
  • (3) 查看归档文件中的文件列表
    tar -t -f /PATH/FILE.tar
  • (4) 展开归档
    tar -x -f /PATH/FILE.tar
    tar -x -f /PATH/FILE.tar -C /PATH/
  • (5) 结合压缩工具实现:归档并压缩
    -j: bzip2, -z: gzip, -J: xz
  • -exclude 排除文件
    tar zcvf /root/a3.tgz --exclude=/app/host1 --exclude=/app/host2 /app
  • -T 选项指定输入文件 -X 选项指定包含要排除的文件列表
    tar zcvf mybackup.tgz -T /root/includefilelist -X /root/excludefilelist
  • split:分割一个文件为多个文件
      split -b Size –d tar-file-name prefix-name
      split -b 1M –d mybackup.tgz mybackup-parts
      split -b 1M mybackup.tgz mybackup-parts
      合并:cat mybackup-parts* > mybackup.tar.gz
cpio

功能:复制文件从或到归档 cpio命令是通过重定向的方式将文件进行打包备份,还原恢复的工具,它可以解压以“.cpio”或者“.tar”结尾的文 件
cpio [选项] > 文件名或者设备名
cpio [选项] < 文件名或者设备名
选项

  • -o 将文件拷贝打包成文件或者将文件输出到设备上
  • -O filename 输出到指定的归档文件名
  • -A 向已存在的归档文件中追加文件
  • -i 解包,将打包文件解压或将设备上的备份还原到系统
  • -I filename 对指定的归档文件名解压
  • -t 预览,查看文件内容或者输出到设备上的文件内容
  • -F filename 使用指定的文件名替代标准输入或输出
  • -d 解包生成目录,在cpio还原时,自动的建立目录
  • -v 显示打包过程中的文件名

mybackup-parts* > mybackup.tar.gz

cpio

功能:复制文件从或到归档 cpio命令是通过重定向的方式将文件进行打包备份,还原恢复的工具,它可以解压以“.cpio”或者“.tar”结尾的文 件
cpio [选项] > 文件名或者设备名
cpio [选项] < 文件名或者设备名
选项

  • -o 将文件拷贝打包成文件或者将文件输出到设备上
  • -O filename 输出到指定的归档文件名
  • -A 向已存在的归档文件中追加文件
  • -i 解包,将打包文件解压或将设备上的备份还原到系统
  • -I filename 对指定的归档文件名解压
  • -t 预览,查看文件内容或者输出到设备上的文件内容
  • -F filename 使用指定的文件名替代标准输入或输出
  • -d 解包生成目录,在cpio还原时,自动的建立目录
  • -v 显示打包过程中的文件名
                                      若不自宫,亦可练成
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值