1 .创建shell脚本
第一步:使用文本编辑器来创建文本文件(后缀需要加 .sh)
第一行必须包括shell声明序列:#! #!/bin/bash 添加注释 注释以#开头
第二步:运行脚本 给予执行权限,在命令行上指定脚本的绝对或相对路径 直接运行解释器,将脚本作为解释器程序的参数运行
shell脚本的调试
bash -n +脚本 检查脚本的语法错误
bash -x +脚本 调试执行脚本
脚本写完后需要加上执行权限:chmod +x 脚本名
定义变量
变量的命名:1、不能使程序中的保留字:例如if, for
2、只能使用数字、字母及下划线,且不能以数字开头
3、见名知义
4、统一命名规则:驼峰命名法 (又分为大小驼峰:大驼峰;每个单词的首字母都要大写 小驼峰;除了首个单词首字母不需要大写外其他单词的首字母都要大写)
变量的种类:
局部变量:生效范围为当前shell进程;对当前shell之外的其它shell进程,包括 当前shell的子shell进程均无效(即使在子进程将变量更改后重新定义为全局变量,父进程的变量也不会更改)
环境(全局)变量:生效范围为当前shell进程及其子进程 (将局部变量生成全局变量用export +变量名)
本地变量:生效范围为当前shell进程中某代码片断,通常指函数
位置变量:$1, $2, …来表示,用于让脚本在脚本代码中调用通过命令行传递给它 的参数
特殊变量:$?, $0(脚本的名称), $*(所有的参数), $@, $#(参数的个数),$$
变量的删除 :unset + 加变量名
只读和位置变量
只读变量:只能声明,但不能修改和删除
声明只读变量: readonly name declare -r name 查看只读变量: readonly –p
位置变量:在脚本代码中调用通过命令行传递给脚本的参数
$1, $2, …:对应第1、第2等参数,shift [n]换位置
$0: 命令本身 $*: 传递给脚本的所有参数,全部参数合为一个字符串
$@: 传递给脚本的所有参数,每个参数为独立字符串
$#: 传递给脚本的参数的个数
$@ $* 只在被双引号包起来的时候才会有差异
set — 清空所有位置变量
进程使用退出状态来报告成功或失败 0 代表成功,1-255代表失败 (用echo $?来执行显示)
bash自定义退出状态码 exit [n]:自定义退出状态码 注意:脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命 令后面的数字
算术运算
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)
echo $[$RANDOM%50] :0-49之间随机数
赋值
增强型赋值:
+=, -=, *=, /=, %=
let varOPERvalue 例如:let count+=3
自加3后自赋值
自增,自减:
let var+=1
let var++
let var-=1
let var–
与和或
& 并且 and
| 或者 or
0&0=0
0&1=0
1&0=0
1&1=1
0|0=0
0|1=1
1|0=1
1|1=1
短路与 &&
短路或 ||
0&&0=0 0||0=0
0&&1=0 0||1=1
1&&0=0 1||0=1
1&&1=1 1||1=1
cmd1 && cmd2
如果cmd1为假,cmd2不需要执行,反之cmd1为真,需要cmd2执行
cmd1 || cmd2
如果cmd1为真,cmd2不需要执行,反之cmd1为假,需要cmd2执行
XOR 异或
0^1=1
0^0=0
1^0=1
1^1=0
10
11
01
a=100
b=110
c=010
100=a
test条件测试语句
长格式的例子: test “$A” = “$B” && echo “Strings are equal” test “$A”-eq “$B” && echo “Integers are equal”
简写格式的例子: [ “$A” = “$B” ] && echo “Strings are equal” [ “$A” -eq “$B” ] && echo “Integers are equal
数值测试:
-gt 是否大于 ( [ $a -gt 12 ]既$a是否大于12)
-ge 是否大于等于
-eq 是否等于
-ne 是否不等于
-lt 是否小于
-le 是否小于等于
-v (可以查看变量是否被设置例如[ -v a ] && echo ” set “如果被设置则显示set其中变量a不需要加$符号 )
一般一个[ ]就可以但在正则表达式中需要用[[ ]]其中括号与内容要用空格隔开
bash的字符串测试
字符串测试:
= 是否等于
> ascii码是否大于ascii码
< 是否小于
!= 是否不等于
=~ 左侧字符串是否能够被右侧的PATTERN所匹配 注意: 此表达式一般用于[[ ]]中;扩展的正则表达式
-z “STRING“ 字符串是否为空,空为真,不空为假
-n “STRING“ 字符串是否不空,不空为真,空为假
注意:用于字符串比较时的用到的操作数都应该使用引号
Bash的文件测试
存在性测试
-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权限
使用read命令来接受输入 (默认功能是对变量赋值 例如read name;之后输入2 ;echo $name )
使用read来把输入值分配给一个或多个shell变量
-p 指定要显示的提示
-s 静默输入,一般用于密码
-n N 指定输入的字符长度N
-d ‘字符’ 输入结束符
-t N TIMEOUT为N秒 read 从标准输入中读取值,给每个单词分配一个变量
所有剩余单词都被分配给最后一个变量 read -p “Enter a filename: “ FILE
bash的配置文件
按生效范围划分,存在两类:
全局配置:(对所有用户都有效)
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
个人配置:
~/.bash_profile
~/.bashrc
2.locate和find命令
区别:locate命令搜索快速占用cpu资源少(利用索引数据搜索的)模糊搜索,无法及时搜到最新的文件,需要手动更新索引数据库(updatedb)主要用于变化不平凡的文件搜索。
;find命令搜索速度慢占用资源多(他是在全磁盘中逐个搜索)可以搜到最新的文件,可精确匹配文件。参数众多可以自定义各种变量搜索你所需要的文件。可能只搜索用户具备读取和执行权限的目录 。
find
查找条件
指搜索层级 -maxdepth level 最大搜索目录深度,指定目录为第1级
-mindepth level 最小搜索目录深度 根据文件名和inode查找:
(指定文件目录为第三层 find /etc/ -maxdepth 3 -mindepth 3 -name f2)
-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:查找没有属组的文件
根据文件大小来查找:
-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: 精确权限匹配(find /etc/ perm 666,精确匹配文件必须为666的权限)
/MODE:任何一类(u,g,o)对象的权限中只要能一位匹配即可,或关系,+ 从centos7开始淘汰
(或的关系 find -perm /666 既只要有一位6匹配即可)
-MODE:每一类对象都必须同时拥有指定权限,与关系 0 表示不关注
(大于的关系find -perm 333 ,匹配只要大于等于333的权限文件都行)
• find -perm 755 会匹配权限模式恰好是755的文件 • 只要当任意人有写权限时,find -perm +222就会匹配 • 只有当每个人都有写权限时,find -perm -222才会匹配 • 只有当其它人(other)有写权限时,find -perm -002才会匹配
处理动作
-print:默认的处理动作,显示至屏幕
-ls:类似于对查找到的文件执行“ls -l”命令
-delete:删除查找到的文件
-fls file:查找到的所有文件的长格式信息保存至指定文件中
-ok COMMAND {} \; 对查找到的每个文件执行由COMMAND指定的命令,对于 每个文件执行命令之前,都会交互式要求用户确认
find示例
备份配置文件,添加.orig这个扩展名 find -name “*.conf” -exec cp {} {}.orig \;
提示删除存在时间超过3天以上的joe的临时文件 find /tmp -ctime +3 -user joe -ok rm {} \;
在主目录中寻找可被其它用户写入的文件 find ~ -perm -002 -exec chmod o-w {} \;
查找/data下的权限为644,后缀为sh的普通文件,增加执行权限 find /data –type f -perm 644 -name “*.sh” –exec chmod 755 {} \;
查看/home的目录 find /home –type d -ls
练习
1、查找/var目录下属主为root,且属组为mail的所有文件 (find /var /( -user root -a -group mail/))或者find /var -user root -group mail
2、查找/var目录下不属于root、lp、gdm的所有文件
find /var -not \( -user root -o -usr lp -o -usr gdm \)
3、查找/var目录下最近一周内其内容修改过,同时属主不为root,也不是 postfix的文件
find /var -mtime -7 -not \( -user root -o -user postfix \)
4、查找当前系统上没有属主或属组,且最近一个周内曾被访问过的文件
find / -atime -7 -nouser -o -nogroup
5、查找/etc目录下大于1M且类型为普通文件的所有文件
find /etc -size +1M -type f
6、查找/etc目录下所有用户都没有写权限的文件
find /etc -not -perm /222 -ls
7、查找/etc目录下至少有一类用户没有执行权限的文件
find /etc -not -perm /222
8、查找/etc/init.d目录下,所有用户都有执行权限,且其它用户有写权限的文件
find /etc/init.d -perm -111 -a -perm -002 或者find /etc/init.d -perm -113
压缩解压及归档工具
compress/uncompress
compress [-dfvcVr] [-b maxbits] [file …] -d: 解压缩,相当于uncompress -c: 结果输出至标准输出,不删除原文件 -v: 显示详情 uncompress 解压缩 zcat file.Z >file
gzip/gunzip
gzip [OPTION]… FILE … -d: 解压缩,相当于gunzip -c: 将压缩或解压缩的结果输出至标准输出 -#:1-9,指定压缩比,值越大压缩比越大 zcat:不显式解压缩的前提下查看文本文件内容
bzip2/bunzip2/bzcat
bzip2 [OPTION]… FILE … -k: keep, 保留原文件 -d:解压缩 -#:1-9,压缩比,默认为9
xz/unxz/xzcat
xz [OPTION]… FILE … -k: keep, 保留原文件 -d:解压缩 -#:1-9,压缩比,默认为6 xzcat: 不显式解压缩的前提下查看文本文件内容
zip/unzip
打包压缩 zip –r /testdir/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/TO/SOMEFILE.tar FILE…
(2) 追加文件至归档: 注:不支持对压缩文件追加 tar -r -f /PATH/TO/SOMEFILE.tar FILE…
(3) 查看归档文件中的文件列表 tar -t -f /PATH/TO/SOMEFILE.tar
(4) 展开归档 tar -x -f /PATH/TO/SOMEFILE.tar tar -x -f /PATH/TO/SOMEFILE.tar -C /PATH/
(5) 结合压缩工具实现:归档并压缩 -j: bzip2 ;bz2, -z: gzip ;gz, -J: xz;xz
(实现既打包同时压缩;tar -zcvpf data.tar.gz /data 讲的是将/data目录下的文件先打包成。tar格式同时压缩成.gz格式的文件 -z和gzip 匹配使用)
解压 tar -xvf data.tar.gz -c /指定目录 解压是都使用-xvf就可以了 后面跟不同的文件格式及目录路径 默认当前路径
sed工具
用法: sed [option]… ‘script’ inputfile…
常用选项:
-n:不输出模式空间内容到屏幕,即不自动打印
-e: 多点编辑 (可以操作多次 )例如sed -n -e ‘1~2p’ -e ‘2p’ /etc/passwd
-f:/PATH/SCRIPT_FILE: 从指定文件中读取编辑脚本
-r: 支持使用扩展正则表达式
-i.bak: 备份文件并原处编辑
script: ‘地址命令’
地址定界:
(1) 不给地址:对全文进行处理
(2) 单地址: #: 指定的行,$:最后一行 /pattern/:被此处模式所能够匹配到的每一行(可定义//里的内容来搜索)例如/^s/搜以s开头的行 /^e/,/^h/及搜素以e开头以h结尾的行。
(3) 地址范围: #,# #,+# /pat1/,/pat2/ #,/pat1/
(4) ~:步进 1~2 奇数行 2~2 偶数行 例如sed -n ‘1~2p’ /etc/passwd 打印奇数行 sed -n ‘2~2p’ /etc/passwd 打印偶数行
编辑命令:
d: 删除模式空间匹配的行,并立即启用下一轮循环
p:打印当前模式空间内容,追加到默认输出之后
a [\]text:在指定行后面追加文本 支持使用\n实现多行追加
i [\]text:在行前面插入文本
c [\]text:替换行为单行或多行文本
w /path/somefile: 保存模式匹配的行至指定文件
!:模式空间中匹配行取反处理
sed -e ‘/^#NameVirtual/s/#//’ -e ‘/^#<VirtualHost/,/^#<\/VirtualHost/s/#//’ /etc/httpd/conf/httpd.conf 此案例使用先搜索后替代并使用多点编辑 ,前面搜索的为单个定义的行,后面搜索的为自定义的行 /q/,/w/ 及q到w的行
s///:查找替换,支持使用其它分隔符,s@@@,s### 替换标记:
g: 行内全局替换
p: 显示替换成功的行
w /PATH/TO/SOMEFILE:将替换成功的行保存至文件中
sed ‘2p’ /etc/passwd
sed –n ‘2p’ /etc/passwd
sed –n ‘1,4p’ /etc/passwd
sed –n ‘/root/p’ /etc/passwd
sed –n ‘2,/root/p’ /etc/passwd 从2行开始
sed -n ‘/^$/=’ file 显示空行行号
sed –n –e ‘/^$/p’ –e ‘/^$/=’ file
sed ‘/root/a\superman’ /etc/passwd行后
sed ‘/root/i\superman’ /etc/passwd 行前
sed ‘/root/c\superman’ /etc/passwd 代替行
sed ‘/^$/d’ file
sed ‘1,10d’ file nl /etc/passwd |
sed ‘2,5d’ nl /etc/passwd |
sed ‘2a tea’
sed ‘s/test/mytest/g’ example
sed –n ‘s/root/&superman/p’ /etc/passwd 单词后
sed –n ‘s/root/superman&/p’ /etc/passwd 单词前
sed -e ‘s/dog/cat/’ -e ‘s/hi/lo/’ pets
sed –i.bak ‘s/dog/cat/g’ pets
高级编辑命令
P:打印模式空间开端至\n内容,并追加到默认输出之前
h: 把模式空间中的内容覆盖至保持空间中
H:把模式空间中的内容追加至保持空间中
g: 从保持空间取出数据覆盖至模式空间
G:从保持空间取出内容追加至模式空间
x: 把模式空间中的内容与保持空间中的内容进行互换
n: 读取匹配到的行的下一行覆盖至模式空间
N:读取匹配到的行的下一行追加至模式空间
d: 删除模式空间中的行
D:如果模式空间包含换行符,则删除直到第一个换行符的模式空间中的文本, 并不会读取新的输入行,而使用合成的模式空间重新启动循环。如果模式空间 不包含换行符,则会像发出d命令那样启动正常的新循环
sed示例
sed -n ‘n;p’ FILE
sed ‘1!G;h;$!d’ FILE
sed ‘N;D‘ FILE
sed ‘$!N;$!D’ FILE
sed ‘$!d’ FILE
sed ‘G’ FILE
sed ‘g’ FILE
sed ‘/^$/d;G’ FILE
sed ‘n;d’ FILE
sed -n ‘1!G;h;$p’ FILE
练习
1、删除centos7系统/etc/grub2.cfg文件中所有以空白开头的行行首的空白字符
cat /etc/grub2.cfg | sed -r ‘s/(^[[:space:]])(.*)/\2/’
2、删除/etc/fstab文件中所有以#开头,后面至少跟一个空白字符的行的行首的# 和空白字符
cat /etc/fstab | sed -r ‘s/(^#[[:space:]]+)(.*)/\2/’
3、在centos6系统/root/install.log每一行行首增加#号
cat /root/install.log | sed ‘s/I/#I/’
4、在/etc/fstab文件中不以#开头的行的行首增加#号
cat /etc/fstab | sed ‘s/^[^#]/#/’
5、处理/etc/fstab路径,使用sed命令取出其目录名和基名
echo “/etc/fstab” | sed -r ‘s@(.*\/)([^\/]+$)@\1@’取路径
echo “/etc/fstab” | sed -r ‘s@(.*\/)([^\/]+$)@\2@’取基名
6、利用sed 取出ifconfig命令中本机的IPv4地址
ifconfig | sed -n ‘2p’ | sed -r ‘s/(.*addr:)(.*)(Bcast.*)/\2/’ centos6上用
7、统计centos安装光盘中Package目录下的所有rpm文件的以.分隔倒数第二个 字段的重复次数
ls /media/CentOS_6.9_Final/Packages/ | sed -r ‘s/(.*\.)(.*)(\.rpm)/\2/’ | sort | uniq -c | sort -nr
8、统计/etc/init.d/functions文件中每个单词的出现次数,并排序(用grep和 sed两种方法分别实现)
cat /etc/init.d/functions | grep -o “[[:alpha:]]\+” | sort | uniq -c | sort -rn
cat /etc/init.d/functions | sed -r ‘s/[^[:alpha:]]/\n/g’ | sed ‘/^$/d’ | sort | uniq -c | sort -rn
9、将文本文件的n和n+1行合并为一行,n为奇数行
cat /etc/init.d/functions|tr -c ‘[:alpha:]’ ‘\n’|tr -s ‘\n’|sort|uniq -c|sort -nr
本文来自投稿,不代表Linux运维部落立场,如若转载,请注明出处:http://www.178linux.com/95597