Linux shell 三十六计

本文修改自《DevOps三十六计》中的Linux shell三十六计篇,原文作者阿铭,著有《跟阿铭学Linux》一书。

特殊命令

第一计

date可以格式化输出时间,定义文件名的前缀或者后缀。如:

[root@VM_0_9_centos logs]# ls
server.2018-07-02.log  server.2018-07-12.log  server.2018-08-01.log  server.2018-08-02.log
[root@VM_0_9_centos logs]# date
Sat Aug  4 16:24:57 CST 2018
[root@VM_0_9_centos logs]# date -d '2 days ago' +%Y-%m-%d
2018-08-02
[root@VM_0_9_centos logs]# date +%Y-%m-%d
2018-08-04
[root@VM_0_9_centos logs]# rm *`date -d '2 days ago' +%Y-%m-%d`.log
rm: remove regular empty file ‘server.2018-08-02.log’? y
[root@VM_0_9_centos logs]# ls
server.2018-07-02.log  server.2018-07-12.log  server.2018-08-01.log
[root@VM_0_9_centos logs]#
#笔者经常用这个命令匹配日志文件,然后放到crontab定时任务中,定时删除一定时间前的无用日志。
#不过,习惯上的`date +"%Y%m%d_%H:%M"` 和 $(date +"%Y%m%d_%H:%M")在crontab下不起作用,需采用如下形式 `date +"\%Y\%m\%d_\%H:\%M"` 和 $(date +"\%Y\%m\%d_\%H:\%M")

第二计

read -p可以实现用户交互。

第三计

exec 1>/tmp/1.log 2>/tmp/error.log可以定义正确输出和错误输出。

第四计

mkpasswd可生成随机字符串。

第五计

test可用于判定某条件是否成立,作为逻辑判断条件。

第六计

sleep可定义休眠时间,用于循环脚本中。

第七计

true和while可实现死循环,例如”while true”,它等同于”whiel:”。

第八计

在循环体里面巧用break或continue,可控制循环体结束或者继续。

第九计

echo -e识别换行符”\n”,echo -n忽略换行符。

第十计

嵌入文档(Here Documents)将脚本中自定义文本内容作为指定命令的输入,典型用法:cat << EOF。

正则三剑客

第十一计

正则表达式中特殊符号含义要搞清楚。”.”表示任意字符,”*”表示它前面的字符有0个或多个,”+”表示它前面的字符有1个或多个,”?”表示它前面的字符有0个或1个,”.*”表示任意个任意字符。

第十二计

grep的选项”–color”,将匹配的关键字显示为红色,方便定位。

第十三计

grep的”-E”选项支持扩展正则(表达式中含有”+” “?” “{}” “()” “|”等符号)匹配,如,grep -E ‘aaa|bbb’ filename,将匹配包含aaa或bbb的行。

第十四计

grep的”-r”选项实现遍历目录下所有文件。

第十五计

sed的”-i”选项直接修改文件内容。

第十六计

sed的”-r”选项支持扩展正则匹配,类似grep的”-E”选项。

第十七计

sed可以调换一个字符串里不同字段的位置,例如调换第一个单词和最后一个单词的位置。

第十八计

awk的”-F”选项指定的分隔符可以是一个正则表达式,如awk -F ‘(:|#)’,分隔符可以是”:”或”#”。

第十九计

awk调用shell的变量,需要做一个特殊处理:a=1;awk -v b=$a’{print b}’。

第二十计

awk可以进行数学计算,并且可以结合循环实现计算某一段的综合,如,awk -F ‘:’ ‘{sum += $3} END {print sum}’ /etc/passwd。

shell特殊符号

第二十一计

特殊符号”||”用在两条命令中间,表示左边的命令执行不成功时才会执行其右边的命令。

第二十二计

特殊符号”$”通常用来表示一个变量,如,a=1;echo $a。在shell中自身也有诸多自带变量,比如,”$1”为第一个参数,”$2”为第二个参数,依次类推。”$#”表示参数个数。”$”符号的用法还有很多,比如检查一条命令是否执行成功,根据返回值”$?”的值来判定。在正则表达式中,”$”表示结尾。

第二十三计

特殊符号”&&”也是在两条命令中间使用,但它和”||”含义正好相反:当其左边命令执行成功时才会执行其右边的命令。

第二十四计

反引号”`”(反引号在键盘左上角的波浪号键上)会将命令结果赋值给变量,方便调用。如:

[root@VM_0_9_centos ~]# ls
abc.txt  ac.txt  anaconda-ks.cfg  a.txt  b.txt  test
[root@VM_0_9_centos ~]# result=`ls *.txt`
[root@VM_0_9_centos ~]# echo $result
abc.txt ac.txt a.txt b.txt
[root@VM_0_9_centos ~]#

第二十五计

管道符号”|”会将其左边命令的输出内容作为右边命令的输入内容。

第二十六计

通配符号”*”和正则表达式中的”*”含义不同,在shell里面它表示通配,如ls *.txt会把所有.txt为后缀的文件全部列出来。

第二十七计

转义符号”\”会将特殊符号变为普通字符。如ls *.txt会把所有.txt文件列出来,但如果使用ls \*.txt则只会把*.txt列出来,这里的”*.txt”就是文件的名字。

第二十八计

注释符号”#”后面的字符不再被shell解释。为了让shell脚本更容易被人读懂,应该加一些说明文字,这些文字的行首要加上”#”。

第二十九计

特殊符号”?”在shell中代表任何一个字符。比如ls ?.txt只把1.txt、2.txt、a.txt等列出来,而不会列出12.txt、aaa.txt。如:

[root@VM_0_9_centos ~]# ls
abc.txt  ac.txt  anaconda-ks.cfg  a.txt  b.txt  test
[root@VM_0_9_centos ~]# ls a?.txt
ac.txt

shell技巧

第三十计

test -n “$a”可以判断变量a是否不为空,test -z “$a”可以判断变量a是否为空,两者正好相对。如:

[root@VM_0_9_centos ~]# a=`test -n "$b"`
[root@VM_0_9_centos ~]# echo $?
1
#上一行返回false,说明test -n "$b"的结果是false,即变量b是空,因为我们之前没定义这个变量
[root@VM_0_9_centos ~]# b=123
[root@VM_0_9_centos ~]# a=`test -n "$b"`
[root@VM_0_9_centos ~]# echo $?
0
#由于定义了b=123,这次返回的就是true

第三十一计

可以把一条命令作为if的判断条件,在shell脚本里很多情况下需要先判断一条命令是否执行成功,判断依据是根据命令执行后$?返回值是否是0。

第三十二计

如果在脚本中要处理的文本内容比较多,可以先存储到一个临时文件里,这样比存储到变量里更加方便,有时甚至是必要的,比如要处理超大文件时,全放变量里就等于放在了内存里。

第三十三计

调试脚本用-x,可以看到每一步运行过程,从而精准定位问题点。

第三十四计

crontab最小时间单元为分钟,while死循环结合sleep可以实现秒级的计划任务。

第三十五计

虚拟终端screen非常实用,虽然不能在shell脚本里面用,但是在调试脚本或者运行常驻脚本时,使用虚拟终端是非常方便的。

第三十六计

expect脚本可以实现自动执行交互式的命令,例如远程登录一台Linux服务器,并执行若干条命令,执行完后再退出。结合shell的for循环,可以实现批量操作。

其实笔者还有一些经常使用的命令推荐:


  • lsof

lsof -i:port命令可以查看端口是否被占用,如:
[root@VM_0_9_centos ~]# lsof -i:8081
COMMAND   PID USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
java    26271 root  116u  IPv4 87571136      0t0  TCP *:tproxy (LISTEN)
[root@VM_0_9_centos ~]# lsof -i:8080
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
java    27382 root   49u  IPv4 281971      0t0  TCP *:webcache (LISTEN)
[root@VM_0_9_centos ~]# lsof -i:8082
[root@VM_0_9_centos ~]#
#可见,8080和8081都被占用了,8082没有被占用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章