1. 程式人生 > 實用技巧 >shell腳本系列:常用工具

shell腳本系列:常用工具

Linux中有很多非常實用的工具或命令,靈活運用這些工具,可以幫助我們在Shell程式設計中化繁為簡,如虎添翼。可能一個工具或命令就能讓原本負責的問題快速解決,本章節我們來一起豐富我們的工具庫,日常可以多積累總結,幫助我們更好的編寫Shell。

1. sort

簡介:顧名思義,就是用來排序的工具,在我們日常工作中對於重複列的多行輸出,如果想要對內容按照特定規則排序,此時就用到了sort工具。

原理:sort 將檔案的每一行作為一個單位,相互比較,比較原則預設情況是從首字元向後,依次按 ASCII 碼值進行比較, 後將他們按升序輸出。

語法:sort [OPTION]... [FILE]…

選項說明:

  • -t:指定以什麼作為列分割
  • -k:用來制定利用那列進行排序,通常-t於-k配合使用
  • -r:將文字檔案降序輸出
  • -n:以陣列來進行生序排序
  • -f:忽略大小寫字母
  • -u:取消重複的行

在此我們不全部展開起所有選項,只根據日常經驗結合實際案例列舉最常用的選項進行說明。

例項:

  • 對/etc/passwd中以uid從大到小排序
[root@test-server ~]# sort -t: -k3 -n -r /etc/passwd
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
halt:x:7:0:halt:/sbin:/sbin/halt
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
sync:x:5:0:sync:/sbin:/bin/sync
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
root:x:0:0:root:/root:/bin/bash

通過上例可以看到,利用-t選項指定/etc/passwd檔案中,以:作為列進行分割,指定uid的列為k3-n以數字進行排序,-r為倒序排序輸出。

2. uniq

簡介:對於一些重複輸出的行進行去重。

語法:uniq [OPTION]... [INPUT [OUTPUT]]

選項說明:

  • -c: 打印出現的次數,只能統計相鄰的;
  • -d: 只打印重複行;
  • -u: 只打印不重複行;
  • -D: 只打印重複行,並且把所有重複行打印出來。

例項:

  • 對/etc/passwd中以:,對最後一列求出現的次數
[root@test-server ~]# 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
[root@test-server ~]# awk -F":" '{print $NF}' /etc/passwd |sort |uniq -c |sort -nr
     14 /sbin/nologin
      1 /sbin/shutdown
      1 /sbin/halt
      1 /bin/sync
      1 /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    b/d/c/p/l/f           #查是塊裝置、目錄、字元裝置、管道、符號連結、普通檔案
- -size      n [c]               #查長度為 n 塊 [或 n 位元組] 的檔案
- -depth                         #使查詢在進入子目錄前先行查詢完本目錄
- -prune                        #通常和 -path 一起使用,用於將特定目錄排除在搜尋條件之外。過濾條件寫在其他條件前面。

在此我們對命令支援的選項全部展開詳解,根據日常經驗結合實際案例列舉最常用的選項進行說明:

例項:

  • 在當前目錄尋找檔名稱以.txt結尾的檔案並打印出來
[root@master ~]# find   ~   -name   "*.txt"   -print 
/root/kubesphere-all-advanced-2.0.2/scripts/os/requirements.txt
/root/kubesphere-all-advanced-2.0.2/kubesphere/roles/storages/NFS-Server/files/nfs-server-provisioner/templates/NOTES.txt
/root/kubesphere-all-advanced-2.0.2/kubesphere/roles/ks-devops/jenkins/files/jenkins/jenkins-update-center/templates/NOTES.txt
/root/kubesphere-all-advanced-2.0.2/kubesphere/roles/ks-devops/harbor/files/harbor/harbor/templates/NOTES.txt
/root/kubesphere-all-advanced-2.0.2/kubesphere/roles/metrics-server/files/metrics-server/templates/NOTES.txt
/root/kubesphere-all-advanced-2.0.2/kubesphere/roles/openpitrix/files/openpitrix/kubernetes/password.txt
  • 查詢 /usr/bin 目錄下大於 10M 的檔案
[root@master ~]# find /usr/bin -size +10000k -exec ls -ld {} \; 
-rwxr-xr-x. 1 root root 13606800 Jul 10  2018 /usr/bin/ceph-dencoder
-rwxr-xr-x. 1 root root 15863688 Jul 10  2018 /usr/bin/ceph-objectstore-tool
-rwxr-xr-x. 1 root root 15589080 Jul 10  2018 /usr/bin/ceph-osd
-rwxr-xr-x. 1 root root 33073928 Feb 10  2019 /usr/bin/docker
-rwxr-xr-x. 1 root root 38088856 Feb 10  2019 /usr/bin/docker-containerd
-rwxr-xr-x. 1 root root 68608416 Feb 10  2019 /usr/bin/dockerd
-rwxr-xr-x. 1 root root 20895160 Feb 10  2019 /usr/bin/docker-containerd-ctr
-rwxr-xr-x. 1 root root 10785264 Jul 10  2018 /usr/bin/ceph-mon
  • 查詢當前目錄下許可權為 777 的檔案
[root@master ~]# find . -perm 777 -print   
./.helm/repository/cache/local-index.yaml
./kubesphere-all-v2.1.0/k8s/extra_playbooks/inventory
./kubesphere-all-v2.1.0/k8s/extra_playbooks/roles
./kubesphere-all-v2.1.0/k8s/contrib/terraform/openstack/hosts

4. date

在我們編寫 Shell 的時候經常遇到需要記錄日誌的情況,在記錄日誌的時候需要打上時間戳,以便後期檢視那個時間節點執行執行的操作,此時就需要用到 date 命令

簡介:date 可以用來顯示或設定系統的日期與時間。

選項:

-d<字串>:顯示字串所指的日期與時間。字串前後必須加上雙引號; 
-s<字串>:根據字串來設定日期與時間。字串前後必須加上雙引號; 
-u:顯示GMT; 

時間格式:

%Y -- 年份
%m -- 月份
%d -- 當月第幾天
%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
1
2
3
4
5
6
[root@master ~]# seq 1 6 |xargs -n 2
1 2
3 4
5 6
  • 刪除日誌檔案
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