1. 程式人生 > >Linux 命令列小技巧-持續更新

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 :讓指令碼進入一個條件總為真的迴圈中,也就是製造一個死迴圈,將裡邊的命令一遍遍地重複執行。

dodowhile語句中的關鍵字,它之後的命令會被執行,在它後邊可以放置一個或一系列命令。

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/)。