Shell 常用工具
Linux中有很多非常实用的工具或命令,灵活运用这些工具,可以帮助我们在Shell编程中化繁为简,如虎添翼。可能一个工具或命令就能让原本负责的问题快速解决,本章节我们来一起丰富我们的工具库,日常可以多积累总结,帮助我们更好的编写Shell。
1. sort
简介:顾名思义,就是用来排序的工具,在我们日常工作中对于重复列的多行输出,如果想要对内容按照特定规则排序,此时就用到了sort工具。
原理:sort 将文件的每一行作为一个单位,相互比较,比较原则默认情况是从首字符向后,依次按 ASCII 码值进行比较, 后将他们按升序输出。
语法:sort [OPTION]... [FILE]…
选项说明:
-t:指定以什么作为列分割
-k:用来制定利用那列进行排序,通常
-t
于-k
配合使用-r:将文本文件降序输出
-n:以数组来进行生序排序
-f:忽略大小写字母
-u:取消重复的行
在此我们不全部展开起所有选项,只根据日常经验结合实际案例列举最常用的选项进行说明。
实例:
对/etc/passwd中以uid从大到小排序
[root@10--- ~]# sort -t: -k3 -n -r /etc/passwdsaslauth:x:::Saslauthd user:/var/empty/saslauth:/sbin/nologin gitlab-www:x::::/var/opt/gitlab/nginx:/bin/falsegit:x::::/var/opt/gitlab:/bin/sh gitlab-redis:x::::/var/opt/gitlab/redis:/bin/falsegitlab-psql:x::::/var/opt/gitlab/postgresql:/bin/sh gitlab-prometheus:x::::/var/opt/gitlab/prometheus:/bin/sh mongod:x:::mongod:/var/lib/mongo:/bin/falsenobody:x:::Nobody:/:/sbin/nologin postfix:x::::/var/spool/postfix:/sbin/nologin dbus:x:::System message bus:/:/sbin/nologin sshd:x:::Privilege-separated SSH:/var/empty/sshd:/sbin/nologin vcsa:x:::virtual console memory owner:/dev:/sbin/nologin apache:x:::Apache:/var/www:/sbin/nologin ftp:x:::FTP User:/var/ftp:/sbin/nologin gopher:x:::gopher:/var/gopher:/sbin/nologin games:x:::games:/usr/games:/sbin/nologin operator:x:::operator:/root:/sbin/nologin uucp:x:::uucp:/var/spool/uucp:/sbin/nologin mail:x:::mail:/var/spool/mail:/sbin/nologin halt:x:::halt:/sbin:/sbin/haltshutdown:x:::shutdown:/sbin:/sbin/shutdownsync:x:::sync:/sbin:/bin/sync lp:x:::lp:/var/spool/lpd:/sbin/nologin adm:x:::adm:/var/adm:/sbin/nologin daemon:x:::daemon:/sbin:/sbin/nologin bin:x:::bin:/bin:/sbin/nologin root:x:::root:/root:/bin/bash
通过上例可以看到,利用-t
选项指定/etc/passwd文件中,以:
作为列进行分割,指定uid的列为k3
,-n以数字进行排序,-r
为倒序排序输出。
2. uniq
简介:对于一些重复输出的行进行去重。
语法:uniq [OPTION]... [INPUT [OUTPUT]]
选项说明:
-c: 打印出现的次数,只能统计相邻的;
-d: 只打印重复行;
-u: 只打印不重复行;
-D: 只打印重复行,并且把所有重复行打印出来。
实例:
对/etc/passwd中以
:
,对最后一列求出现的次数
[root@master ~]# awk -F: '{print $NF}' /etc/passwd/bin/bash/sbin/nologin/sbin/nologin/sbin/nologin/sbin/nologin/bin/sync/sbin/shutdown/sbin/halt/sbin/nologin/sbin/nologin/sbin/nologin/sbin/nologin/sbin/nologin/sbin/nologin/sbin/nologin/sbin/nologin/sbin/nologin/sbin/nologin/sbin/nologin/sbin/nologin/bin/nologin/sbin/nologin/sbin/nologin/sbin/nologin/sbin/nologin/sbin/nologin/sbin/nologin[root@master ~]# awk -F: '{print $NF}' /etc/passwd |sort |uniq -c |sort -nr /sbin/nologin /sbin/shutdown /sbin/halt /bin/sync /bin/nologin /bin/bash
先利用awk打印出最后一列内容,之后利用sort 来进行排序,将相同的字符规在一起输出,最后对相同的行进行去重,得出每种不同类型shell出现的次数,最后对数学从大到小排序。
3. find
简介:顾名思义,就是用来在系统中查找文件的工具,可以指定一个基础起始目录,根据不同的选项查找不同的文件。
语法:find path -option [ -print ] [ -exec -ok command ] {} \;
原理:find 根据option在指定的系统路径中查找文件,如果查找到与对应的exec命令,则执行对应的command。
print: find 命令将匹配的文件输出到标准输出;
exec: find 命令对匹配的文件执行该参数所给出的 shell 命令。相应命令的形式为 ‘command’ {} ;,注意 {} 和 \;之间的空格;
ok: 和 - exec 的作用相同,只不过以一种更为安全的模式来执行该参数所给出的 shell 命令,在执行每一个命令之前,都会给出提示,让用户来确定是否执行;
选项说明:
- -name filename #查找名为 filename 的文件- -perm #按执行权限来查找- -user username #按文件属主来查找- -group groupname #按组来查找- -mtime -n +n #按文件更改时间来查找文件,-n 指 n 天以内,+n 指 n 天以前- -atime -n +n #按文件访问时间来查 GIN: 0px>- -ctime -n +n #按文件创建时间来查找文件,-n 指 n 天以内,+n 指 n 天以前- -type ///p/l/ #查是块设备、目录、字符设备、管道、符号链接、普通文件- -size n [] #查长度为 n 块 [或 n 字节] 的文件- -depth #使查找在进入子目录前先行查找完本目录- -prune #通常和 -path 一起使用,用于将特定目录排除在搜索条件之外。过滤条件写在其他条件前面。
在此我们对命令支持的选项全部展开详解,根据日常经验结合实际案例列举最常用的选项进行说明:
实例:
在当前目录寻找文件名称以
.txt
结尾的文件并打印出来
[root@master ~]# find ~ -name *.txt -print /root/kubesphere-all-advanced./scripts/os/requirements.txt/root/kubesphere-all-advanced./kubesphere/roles/storages/NFS-Server/files/nfs-server-provisioner/templates/NOTES.txt/root/kubesphere-all-advanced./kubesphere/roles/ks-devops/jenkins/files/jenkins/jenkins-update-center/templates/NOTES.txt/root/kubesphere-all-advanced./kubesphere/roles/ks-devops/harbor/files/harbor/harbor/templates/NOTES.txt/root/kubesphere-all-advanced./kubesphere/roles/metrics-server/files/metrics-server/templates/NOTES.txt/root/kubesphere-all-advanced./kubesphere/roles/openpitrix/files/openpitrix/kubernetes/password.txt
查找 /usr/bin 目录下大于 10M 的文件
[root@master ~]# find /usr/bin -size +10000k -exec ls -ld {} \; -rwxr-xr-x. root root Jul /usr/bin/ceph-dencoder-rwxr-xr-x. root root Jul /usr/bin/ceph-objectstore-tool-rwxr-xr-x. root root Jul /usr/bin/ceph-osd-rwxr-xr-x. root root Feb /usr/bin/docker-rwxr-xr-x. root root Feb /usr/bin/docker-containerd-rwxr-xr-x. root root Feb /usr/bin/dockerd-rwxr-xr-x. root root Feb /usr/bin/docker-containerd-ctr-rwxr-xr-x. root root Jul /usr/bin/ceph-mon
查找当前目录下权限为 777 的文件
[root@master ~]# find . -perm 777 -print ./.helm/repository/cache/local-index.yaml./kubesphere-all-v2./k8s/extra_playbooks/inventory./kubesphere-all-v2./k8s/extra_playbooks/roles./kubesphere-all-v2./k8s/contrib/terraform/openstack/hosts
4. date
在我们编写 Shell 的时候经常遇到需要记录日志的情况,在记录日志的时候需要打上时间戳,以便后期查看那个时间节点运行执行的操作,此时就需要用到 date 命令
简介:date 可以用来显示或设定系统的日期与时间。
选项:
-<字符串>:显示字符串所指的日期与时间。字符串前后必须加上双引号; -s<字符串>:根据字符串来设置日期与时间。字符串前后必须加上双引号; -u:显示GMT;
时间格式:
%Y -- 年份%m -- 月份% -- 当月第几天%t -- Tab 跳格%H -- 小时,24 小时格式 (0~23)%I -- 小时,12 小时格式 (0~12)%M -- 分钟 (00~59)%S -- 秒 (00~59)%j -- 今年中的第几天%Z -- 以字符串形式输出当前时区%z -- 以数字形式输出当前时区%F -- 文件时间格式 same as % Y-% m-% d%T -- 24 小时制时间表示 (hh:mm:ss)
实例
计算一个命令执行所需要的耗时
#!/bin/bash start=$(date +%s) echo $(date +%F %T) 开始执行命令 sleep 5 echo $(date +%F %T) 执行命令完成 end=$(date +%s) difference=$(( end - start )) echo 执行命令总耗时:$difference seconds. [root@master ~]# bash time.sh 2020-04-19 10:19:58 开始执行命令 2020-04-19 10:20:03 执行命令完成 执行命令总耗时:5 seconds.
5. xargs
简介:xargs 全称是 transform arguments,意为转换参数,它将标准输入转换为命令行参数。因为 linux 命令行中经常要使用到管道符连接不同的命令,但是有些命令不支持标准输入,此时就需要使用 xargs 将标准输入转换为参数,
语法:stdin_input | xargs [option] cmd
原理:xargs 一般是通过管道符接受标准输入并将其转换为命令行参数传递给 cmd。
实例:
将标准输入转换成命令行参数
[root@master ~]# seq 1 6[root@master ~]# seq 1 6 |xargs -n 2
删除日志文件
ls *.log |xargs rm -r f {}
查找 /home/data 下权限为 644 的文件修改权限为 600
find /home/data -perm 644 | xargs chmod 600
查找 jpg 文件并打包
find / -name *.jpg -type f -print | xargs tar -cvzf images.tar.gz
6. 实例
6.1 需求
我们经常在 Linux 系统操作操作文件,俗话说常在河边走,哪有不湿鞋,一不小心删除重要文件是非常危险的。我们可以利用 Shell 脚本来制作一个类似于 Windows 下的回收站,配合定时任务,定期清理这个回收站中的内容,从而达到缓冲及规避危险操作。
6.2 思路
通过 alias rm 来将删除的文件,移动文件到一个回收站目录;
定期的在系统磁盘允许可控的使用率情况下,对回收站目录下的文件进行删除。
6.3 实现
#!/bin/bash# function:自定义rm命令,每天晚上定时清理# 指定变量CMD_SCRIPTS=$HOME/.rm_scripts.sh TRASH_DIR=$HOME/.TRASH_DIR CRON_FILE=/var/spool/cron/root BASHRC=$HOME/.bashrc[ ! -d ${TRASH_DIR} ] && mkdir -p ${TRASH_DIR}cat > $CMD_SCRIPTS <<EOF PARA_CNT=\$#TRASH_DIR=$TRASH_DIRfor i in \$*; do DATE=\$(date +%F%T) fileName=\$(basename \$i) mv \$i \$TRASH_DIR/\$fileName.\$DATEdone EOFsed -i s@$(grep 'alias rm=' $BASHRC)@alias rm='bash ${CMD_SCRIPTS}'@g $BASHRCsource $HOME/.bashrc# 制作定时清理任务echo 0 0 * * * rm -rf $TRASH_DIR/* >> $CRON_FILEecho 删除目录:$TRASH_DIRecho 删除脚本:$CMD_SCRIPTSecho 请执行:source $BASHRC 来加载文件或退出当前shell重新登录
对防治误删除脚本进行系统测试。
[root@10--- ~]# bash custom_rm.sh 删除目录:/root/.TRASH_DIR 删除脚本:/root/.rm_scripts.sh 请执行:source /root/.bashrc 来加载文件或退出当前shell重新登录[root@10--- ~]# rm testdir/[root@10--- ~]# rm wget-log [root@10--- ~]# ls -la .TRASH_DIR/total drwxr-xr-x. root root Apr : .dr-xr-x---. 13 root root 4096 Apr 18 20:11 ..drwxr-xr-x. root root Apr : testdir--::-rw-r--r--. 1 root root 0 Jan 9 21:59 wget-log.2020-04-1820:11:40# 查看定时任务[root@10--- ~]# crontab -l * * * rm -rf /root/.TRASH_DIR/*
7. 小结
Shell 编程就是利用工具加数据结构流程控制实现一组操作,所以掌握更多常用的工具或命令非常利于我们编写 Shell 脚本,平时可以多尝试利用各种命令或工具,并在 Shell 中熟练运用它们,勤练并反思总结,归纳整理,日积月累就会形成自己强大的工具库。