Linux 命令列小技巧-持續更新
概述
你有將Linux物盡其用嗎?有些時候你會需要這些技巧。本博文會幫助你更好得使用一些命令,發揮其更強大的功能。
命令列小技巧
history命令來檢視曾經執行過的命令
# history
history中顯示命令的執行時間
從history命令輸出看,很明顯,命令的執行時間沒有被打出來。有解決方法嗎?有的!執行如下命令:
# HISTTIMEFORMAT="%d/%m/%y %T "
# history
如果你想讓這個修改永久生效,新增如下的一行內容到~/.bashrc檔案中:
export HISTTIMEFORMAT="%d/%m/%y %T "
或者
export HISTTIMEFORMAT="%y-%m-%d %T "
格式自定義即可
然後,在終端中執行:
# source ~/.bashrc
命令和選項的解釋:
history – 檢視執行過的命令
HISTIMEFORMAT – 設定時間格式的環境變數
%d – 天
%m – 月
%y – 年
%T – 時間戳
source – 簡而言之就是將檔案內容傳送給shell來執行
.bashrc – BASH以互動方式啟動時執行的指令碼檔案
- 在命令前插入空格
是的,沒看錯。在命令前面插入空格,這條命令會被 shell 忽略,也就意味著它不會出現在歷史記錄中。但是這種方法有個前提,只有在你的環境變數 HISTCONTROL 設定為 “ignorespace” 或者 “ignoreboth” 才會起作用。在大多數情況下,這個是預設值。
所以,像下面的命令
[space]echo "this is a top secret"
如果你之前執行過如下設定環境變數的命令,那麼上述命令不會出現在歷史記錄中。
export HISTCONTROL=ignorespace
- 禁用當前會話的所有歷史記錄
如果你想禁用某個會話所有歷史,你可以在開始命令列工作前簡單地清除環境變數 HISTSIZE 的值即可。執行下面的命令來清除其值:
export HISTSIZE=0
HISTSIZE 表示對於 bash 會話其歷史列表中可以儲存命令的個數(行數)。預設情況,它設定了一個非零值,
檢視預設值
[root@entel2 ~]# echo $HISTSIZE
1000
- 工作結束後清除整個歷史
這可以看作是前一部分所提方案的另外一種實現。唯一的區別是在你完成所有工作之後執行這個命令。下面是剛說到的命令:
history -cw
剛才已經提到,這個和 HISTSIZE 方法有相同效果。
- 只針對你的工作關閉歷史記錄
雖然前面描述的方法(2 和 3)可以實現目的,它們可以清除整個歷史,在很多情況下,有些可能不是我們所期望的。有時候你可能想儲存直到你開始命令列工作之間的歷史記錄。對於這樣的需求,你開始在工作前執行下述命令:
[space]set +o history
備註:[space] 表示空格。並且由於空格的緣故,該命令本身也不會被記錄。
上面的命令會臨時禁用歷史功能,這意味著在這命令之後你執行的所有操作都不會記錄到歷史中,然而這個命令之前的所有東西都會原樣記錄在歷史列表中。
要重新開啟歷史功能,執行下面的命令:
[Space]set -o history
它將環境恢復原狀,也就是你完成了你的工作,執行上述命令之後的命令都會出現在歷史中。
- 從歷史記錄中刪除指定的命令
現在假設歷史記錄中已經包含了一些你不希望記錄的命令。這種情況下我們怎麼辦?很簡單。直接動手刪除它們。通過下面的命令來刪除:
history | grep "part of command you want to remove"
上面的命令會輸出歷史記錄中匹配的命令,每一條前面會有個數字。
一旦你找到你想刪除的命令,執行下面的命令,從歷史記錄中刪除那個指定的項:
history -d [num]
- 其他
cat | bash #執行這條命令後可以直接在其之後執行其他命令,除了這條命令不會留下其他目錄的歷史,Tab鍵功能不能用
echo > ~/.bash_history #清除當前使用者所有記錄到檔案裡的記錄
history -c #清楚所有歷史紀錄,不能清除檔案裡的
history -d {n} #清除歷史紀錄中指定的某條記錄,{n}為數字
history -d {n} && history -d {x} && history -d {y} #清除指定的多條記錄,包括可以清除自身這條
for i in {99..233}; do history -d $i; done #使用for迴圈清除指定連續的多條命令
獲取吃掉你磁碟空間的最大的5個檔案
一個使用du命令的簡單單行指令碼即可實現,du命令主要用於獲取檔案的空間使用情況。
# du -hsx * | sort -rh | head -5
命令和選項的解釋:
- du – 估計檔案的空間使用情況
- -hsx – (-h)更易讀的格式,(-s)彙總輸出,(-x)跳過其他檔案系統的檔案
- sort – 對文字檔案按行排序
- -rh – (-r)將比較的結果逆序輸出,(-h) for compare human readable format.
- head – 輸出檔案的頭幾行
注意: 只能獲取當前目錄下,不能遞迴子目錄。
可以使用stat命令
# stat filename_ext (例如:stat abc.pdf)
隨機顯示一個man手冊頁
# man $(ls /bin | shuf | head -1)
命令和選項的解釋:
man – Linux man手冊
ls – 列出檔案
/bin – 系統可執行檔案的路徑
shuf – 把輸入內容按行隨機打亂並輸出
head – 輸出檔案的頭幾行
刪除大檔案
有時候檔案可能會變得很大。我看過由於缺乏管理技能一個日誌檔案就超過 250G 的例子。用 rm 命令可能不足以刪除該檔案,因為有大量的資料需要移除。應該避免這個很“笨重”的操作。相反,你可以使用一個簡單的方法解決這個問題:
# > /path-to-file/huge_file.log
當然你需要根據你實際情況替換路徑和檔名。上面的命令寫一個空輸出到該檔案。用更簡單的話說它會清空檔案而不會導致你的系統產生大的 I/O 消耗。
複製檔案到多個目錄
通常使用 cp 命令進行檔案複製。複製檔案通常看起來類似:
# cp /path-to-file/my_file.txt /path-to-new-directory/
現在假設你需要複製該檔案到多個目錄:
# cp /home/user/my_file.txt /home/user/1
# cp /home/user/my_file.txt /home/user/2
# cp /home/user/my_file.txt /home/user/3
這有點荒唐。相反,你可以用簡單的一行命令解決問題:
# echo /home/user/1/ /home/user/2/ /home/user/3/ | xargs -n 1 cp /home/user/my_file.txt
在多個 Linux 伺服器上執行相同命令
將伺服器的 IP 地址寫到檔案 list.txt 中,像上面那樣一行一個。然後執行:
# for in $i(cat list.txt); do ssh [email protected]$i 'bash command'; done
上面的命令中你需要用實際登入的使用者替換 “user”,用你希望執行的實際命令替換 “bash command”。這個方法非常適用於通過使用 SSH 金鑰進行無密碼驗證,因為這樣你不需要每次都為使用者輸入密碼。
注意取決於你 Linux 系統的設定,你可能還需要傳遞一些額外的引數給 SSH 命令。
在指定時間關閉計算機
有時候你需要在下班幾個小時後再關閉計算機。你可以通過使用下面的命令在指定時間關閉你的計算機:
$ sudo shutdown 21:00
這會告訴你在你指定的時間關閉計算機。你也可以告訴系統在指定分鐘後關閉:
$ sudo shutdown +15
這表示計算機會在 15 分鐘後關閉。
用一個命令建立目錄樹
你很可能知道可以使用 mkdir 命令建立新的目錄。因此如果你想建立一個新的目錄,你可能會執行:
# mkdir new_folder
但如果你想在該目錄下建立 5 個子目錄呢?執行 5 次 mkdir 命令並非是一個好的選擇。相反你可以類似下面這樣使用 -p 選項:
# mkdir -p new_folder/{folder_1,folder_2,folder_3,folder_4,folder_5}
最後你會在 new_folder 中有 5 個目錄:
# ls new_folder/
folder_1 folder_2 folder_3 folder_4 folder_5
假設你要建立一個類似於下面很長的/複雜的目錄樹。實現這最有效的方法是什麼呢?
類似下面要實現的目錄樹結構。
$ cd /home/$USER/Desktop
$ mkdir tecmint
$ mkdir tecmint/etc
$ mkdir tecmint/lib
$ mkdir tecmint/usr
$ mkdir tecmint/bin
$ mkdir tecmint/tmp
$ mkdir tecmint/opt
$ mkdir tecmint/var
$ mkdir tecmint/etc/x1
$ mkdir tecmint/usr/x2
$ mkdir tecmint/usr/x3
$ mkdir tecmint/tmp/Y1
$ mkdir tecmint/tmp/Y2
$ mkdir tecmint/tmp/Y3
$ mkdir tecmint/tmp/Y3/z
上述情況可以簡單地通過執行下面一行命令來實現。
$ mkdir -p /home/$USER/Desktop/tecmint/{etc/x1,lib,usr/{x2,x3},bin,tmp/{Y1,Y2,Y3/z},opt,var}
你可以用 tree 命令驗證。如果沒有安裝你可以使用 apt 或 yum 安裝 ‘tree’ 軟體包。
$ tree tecmint
我們可以用上面的方式建立任意複雜的目錄樹結構。注意這僅僅是一個普通的命令,但是用 ‘{}’ 來建立層級目錄。需要的時候如果在 shell 指令碼中使用是非常有用的。
執行之前的命令
很多時候你需要一遍又一遍執行相同的命令。儘管你可以重複按你鍵盤上的向上游標鍵,但你也可以用 history 命令替代。這個命令會列出自從你上次啟動終端以來所有輸入過的命令:
# history
正如你上面看到的,你會得到一個你執行過的命令的列表。每一行中有一個數字表示你在第幾行輸入了命令。你可以通過以下方法重新呼叫該命令:
!#
其中要用命令的實際編號代替 #。
在 Linux 中鎖定或隱藏檔案或目錄
鎖定檔案或目錄最簡單的方法是使用 Linux 檔案許可權。如果你是檔案或目錄的所有者,你可以阻止其他使用者和組訪問(刪除、讀取、寫入、執行)它,如下所示:
$ chmod 700 xgj.info
或
$ chmod go-rwx xgj.info
為了實現對系統中的其他使用者隱藏檔案或目錄,可以通過在檔案或目錄開頭新增 . 的方式重新命名:
$ mv filename .filename
當 sudo 命令執行失敗時怎麼使用 su 命令
雖然 sudo 命令被用來以超級使用者許可權執行命令,但是在某些情況下它也會執行失敗,如下所示。
在這裡,我想清空一個大檔案的內容,其檔名為 uptime.log,但是即便我是使用 sudo 命令也執行失敗了。
$ cat /dev/null >/var/log/uptime.log
$ sudo cat /dev/null >/var/log/uptime.log
遇到這種情況,你需要使用 su 命令切換到 root 使用者,然後像下面這樣去執行清空操作:
$ su
$ sudo cat /dev/null >/var/log/uptime.log
$ cat /var/log/uptime.log
在 Linux 中永久刪除檔案
一般情況下,我們通過使用 rm 命令將檔案從 Linux 系統中刪除。然而,這些檔案並沒有被真正的刪除,它們仍被儲存在那裡並隱藏在你的硬碟中,其他使用者仍然可以在 Linux 中恢復刪除的檔案並檢視。
為了防止這種情況發生,我們可以使用 shred 命令來覆寫檔案內容,並在覆蓋完成後選擇刪除檔案。
$ shred -zvu xgj.tar
上述命令中所使用的選項說明:
-z – 最後一次使用 0 進行覆蓋以隱藏覆寫動作。
-u – 覆寫後截斷並移除檔案。
-v – 顯示詳細過程。
閱讀 shred 手冊以獲取更多的使用資訊。
$ man shred
在 Linux 中重新命名多個檔案
你可以通過使用 rename 命令隨時在 Linux 中重新命名多個檔案。
rename 命令會根據第一個引數中的規則重新命名指定檔案。
以下命令會將所有 .pdf 檔案重新命名為 .doc 檔案,使用的規則為 ‘s/.pdf$/.doc/’:
$ rename -v 's/\.pdf$/\.doc/' *.pdf
在 Linux 中檢查單詞拼寫
look 命令用於顯示檔案中以指定字串為字首的任意行,同時它也可以幫你檢查命令列中給定單詞的拼寫。儘管它並不是那麼有效和可靠,但它仍然算得上是其他強大的拼寫檢查工具的有用替代品。
$ look linu
$ look docum
列出所有 Shell 內建命令
shell 內建命令是一個命令或者函式,從內部呼叫並直接在 shell 裡執行,而不是從硬碟載入外部的可執行程式來執行。
列出所有 shell 內建命令及其語法,執行如下命令:
$ help
如何在不使用Cron的情況排程Linux下的任務
在Linux下,排程一個任務/命令稱之為Cron。當我們需要排程一個任務時,我們會使用Cron,但你知道我們在不使用Cron的情況也可以排程一個在將來時間執行的任務嗎?你可以按照如下建議操作……
每5秒鐘執行一個命令(date)然後將結果寫入到一個檔案(data.txt)。為了實現這一點,我們可以直接在命令提示符執行如下單行指令碼。
$ while true; do date >> date.txt ; sleep 5 ; done &
上述指令碼的解釋:
while true :讓指令碼進入一個條件總為真的迴圈中,也就是製造一個死迴圈,將裡邊的命令一遍遍地重複執行。
do :do是while語句中的關鍵字,它之後的命令會被執行,在它後邊可以放置一個或一系列命令。
date >> date.txt :執行date命令,並將其輸出寫入到data.txt檔案中。注意我們使用>>,而不是>。
>> :對檔案(date.txt)進行追加寫的操作,這樣每次執行命令後,輸出內容會被追加到檔案中。如果使用>的話,則會一遍遍地覆蓋之前的內容。
>
done :while迴圈語句塊結束的標記。
& :將整個程序放到後臺執行。
類似地,我們可以這樣執行任何指令碼。下邊的例子是每100秒執行一個名為script_name.sh的指令碼。
另外值得一提的是上面提到的指令碼檔案必須處於當前目錄中,否則需要使用完整路徑(/home/$USER/…/script_name.sh)。實現如上功能的單行指令碼如下:
$ while true; do /bin/sh script_name.sh ; sleep 100 ; done &
總結:上述的單行指令碼並不是Cron的替代品,因為Cron工具支援眾多選項,更加靈活,可定製性也更高。然而如果我們想執行某些測試,比如I/O評測,上述的單行指令碼也管用。
如何不使用clear命令清空終端的內容
你如何清空終端的內容?你可能會認為這是一個傻問題。好吧,大家都清楚可以使用clear命令。如果養成使用ctrl + l快捷鍵的習慣,我們會節省大量時間。
Ctrl + l快捷鍵的效果和clear命令一樣。所以下一次你就可以使用ctrl + l來清空終端的內容了。
總結:因為ctrl + l是一個快捷鍵,我們不可以在指令碼中使用。所以如果我們需要在指令碼中清空螢幕內容,還是需要使用clear命令。但我能想到的所有其他情況,ctrl + l都更加有效。
在其它目錄執行一個命令,然後自動返回當前工作目錄
這是一個很多人可能不知道的令人吃驚的技巧。你可能想在其它目錄執行任何一個命令,然後再回到當前目錄。要實現這樣的目的,你只需要將命令放在一個圓括號裡。
[root@entel2 ~]# pwd
/root
[root@entel2 ~]# (cd /docker/ && ll)
total 60
drwxr-xr-x 5 root root 4096 Jun 15 2016 aufs
drwx------ 9 root root 4096 Jan 19 15:55 containers
......
[root@entel2 ~]# pwd
/root
[root@entel2 ~]#
相當於在裡面建立了個子shell,裡面的命令執行完後自動退出子shell,故不改變當前工作目錄。
在桌面(/home/$USER/Desktop)建立一個檔案(例如 test)並填入以下內容。
ABC
DEF
GHI
JKL
MNO
PQR
STU
VWX
Y
Z
這種情況一個普通使用者會怎麼做呢?
a. 他首先會建立檔案,最好使用 touch 命令,例如:
$ touch /home/$USER/Desktop/test
b. 他會用一個文字編輯器開啟檔案,這可能是 nano、vim 或其它編輯器。
$ vim /home/$USER/Desktop/test
c. 然後他會將上面的內容輸入到檔案中,儲存並退出。
忽略他/她使用的時間,他至少需要 3 步來執行上面的情況。
一個經驗豐富的 Linux 使用者會怎麼做呢?他會在終端中輸入下面的文字然後就完成所有任務。他不需要單獨執行每一步。
cat << EOF > /home/$USER/Desktop/test
ABC
DEF
GHI
JKL
MNO
PQR
STU
VWX
Y
Z
EOF
Tar 包解壓到指定位置
$ tar -jxvf firefox-37.0.2.tar.bz2 -C /opt/
-C 選項提取檔案到指定目錄(這裡是 /opt/)。