Linux 命令列黑技術(LTS)

pcdack發表於2018-04-18

Linux命令列,是開發人員日常接觸的東西。但是,有很多小技巧。我在這裡做個總結(長期更新)。

Linux 命令列黑技術(LTS)

在路徑間如魚得水

黑技術1:設立根目錄

如果,你經常使用一個目錄作為你的根目錄,那麼,你可以通過CDPATH來指定你的cd根目錄。 例如,我經常到/etc目錄下,來対相應的檔案進行配置。比如我想從我的家目錄到/etc/nginx/目錄下,一般的方法是:

cd /etc/nginx/ 
複製程式碼

有沒有可以偷懶的法子呢?當然有,我們可以在.bashrc(如果你是zsh的話,就在.zshrc下)加入export CDPATH=/etc 現在,你想開啟的/etc/nginx/目錄下,只需要輸入:

cd nginx
複製程式碼

懶人必備。 當然,你可以輸入多個根路徑,只要在每個路徑下用:隔開。

export CDPATH=.:~:/etc:/var:
複製程式碼

黑技術2:在兩個路徑相互切換

當我們經常需要在一個terminal下,在兩個路徑之間,來回切換。這個時候,我們可以使用cd -,在兩個路徑之間“反覆橫跳”。

Linux 命令列黑技術(LTS)

例如:第一個路徑是/etc/nginx/,第二個路徑是~/project/,我們先cd /etc/nginx/下,然後,再cd ~/project/。隨後,當我們需要切換另一個路徑只需要cd -就可以實現。

黑技術3:將路徑通過棧的方式訪問

如果,遇到訪問路徑的過程像棧這種資料結構,那麼我們可以用pushd來解決。 實現過程:

  1. 導航到相應的目錄例如/tmp/push1
  2. 使用pushd命令壓入目錄棧
  3. 在其他路徑下,使用popd命令,導航到棧頂目錄。

例子:

/tmp/目錄下建立來push1,push2,push3三個目錄,需求是將這三個目錄分別壓入目錄棧,然後分別導航到相應的目錄。下面將顯示整個過程:

# pcdack @ pcdack-sword in /tmp/push1 [18:58:01] 
$ pwd
/tmp/push1

# pcdack @ pcdack-sword in /tmp/push1 [18:58:15] 
$ pushd .
/tmp/push1 /tmp ~

# pcdack @ pcdack-sword in /tmp/push1 [18:58:22] 
$ cd /tmp/push2

# pcdack @ pcdack-sword in /tmp/push2 [18:58:31] 
$ pushd .
/tmp/push2 /tmp/push1 /tmp ~

# pcdack @ pcdack-sword in /tmp/push2 [18:58:37] 
$ cd /tmp/push3

# pcdack @ pcdack-sword in /tmp/push3 [19:00:23] 
$ pushd .
/tmp/push3 /tmp/push2 /tmp/push1 /tmp ~

# pcdack @ pcdack-sword in /tmp/push3 [19:00:28] 
$ popd
/tmp/push2 /tmp/push1 /tmp ~

# pcdack @ pcdack-sword in /tmp/push2 [19:00:37] 
$ popd
/tmp/push1 /tmp ~
複製程式碼

整個過程非常簡單,相信大家都能看得懂。

指令碼:

當然我們可以將導航與壓棧操作結合起來,我們可以將下面的程式碼寫到.bashrc或者.zshrc下來實現。

function pushcd(){
    cd "$@" && eval pushd .;
}
複製程式碼

然後,壓棧和切換路徑一個命令解決。

黑技術4:“優雅”的切換上級目錄

如果我們身處一個特別深的目錄下,例如:/dev/bus/usb/001。那麼,我們如何切換到/dev/bus/目錄下咧?一般的做法是cd ../..,這裡只有兩級目錄看似還是可以接受的,但是,如果,有一天,要回退五級目錄。那麼一般的寫法就不優雅了。所以,在這裡要介紹一個黑技術。使用alias來解決問題。在我們的.bashrc或者.zshrc下輸入:

alias ..="cd .."
alias ..2="cd ../.."
alias ..3="cd ../../.."
alias ..4="cd ../../../.."
alias ..5="cd ../../../../.."
複製程式碼

然後,我們回退兩級目錄將變成..2,優雅,快樂,美麗。 當然,也可以用其他表示方法:例如:cd1,cd2...

黑技術5:mkdir與cd的結合

在日常的開發中,我們經常需要建立一個資料夾,並且,導航到這個目錄。但是,為了優(tou)雅(lan)。我們可以把兩個命令和在一起。建立一個新的命令mkdircd。把下面的程式碼新增到.bashrc或者.zshrc下:

function mkdircd(){
    mkdir -p "$@" && eval cd "\"\$$#\"";
}
複製程式碼

這樣就OK了。

原來你是這樣的剪下板

我們經常在terminal中,使用系統剪下板。比如,將一個命令的輸出複製到剪下板,然後,貼上到瀏覽器或其他地方等等的用途。首先,我們需要一個軟體叫xsel。在各大發行版本中的包管理中都有,比如在arch中pacman -S xsel就可以安裝了。

使用

1.將命令輸出到剪下板,比如,我想將ls的結果複製到剪下板中,那麼輸入下面的命令就可以了:

ls | xsel -i -b
複製程式碼

為了更加方便呼叫,我們可以.zshrc或者.bashrc填入如下程式碼:

alias to_clipboard="sel -i -b"
複製程式碼

那麼,剛剛的例子就變成了:

ls | to_clipboard
複製程式碼

當然,我們也可以整合檢視剪下板內容的命令,在.zshrc或是.bashrc中新增:

alias clipboard="xsel -b -o"
複製程式碼

當我們在terminal中輸入clipboard時,就會將剪下板的內容輸出。

壓縮檔案自如操作

黑技術1:萬能解壓命令

在Linux中,壓縮的格式有很多種類,例如,常用的有.tar.gz,zip,tar.bz2等等。解壓命令“又臭又長”,那麼,我們能不能一個命令就可以把所有的壓縮格式的檔案解壓出來咧?當然是可以的,我們只需要將下面指令碼新增到.zshrc或者.bashrc裡,就可以做到一個命令解壓所有:

注意:你的機器裡需要預先安裝了unrar,unzip命令

ex ()
{
  if [ -f $1 ] ; then
    case $1 in
      *.tar.bz2)   tar xjf $1   ;;
      *.tar.gz)    tar xzf $1   ;;
      *.bz2)       bunzip2 $1   ;;
      *.rar)       unrar x $1     ;;
      *.gz)        gunzip $1    ;;
      *.tar)       tar xf $1    ;;
      *.tbz2)      tar xjf $1   ;;
      *.tgz)       tar xzf $1   ;;
      *.zip)       unzip $1     ;;
      *.Z)         uncompress $1;;
      *.7z)        7z x $1      ;;
      *)           echo "'$1' cannot be extracted via ex()" ;;
    esac
  else
    echo "'$1' is not a valid file"
  fi
}
複製程式碼

黑技術2:頭文字“Z”

有些時候,我們需要直接檢視壓縮包裡的內容,而不需要解壓這個壓縮包,那麼我們可以使用z字頭命令。這個系列一共有:

  1. zgrep
  2. zcat
  3. zless
  4. zmore
  5. zdiff 這些命令其實和不帶"z"的功能類似,只不過作用的物件不一樣。"z"命令是專門用在壓縮檔案下的。 例子:
#我先建立幾個文字檔案
echo "this first line">first
gzip first
# 我們通過呼叫z命令來檢視內容
zcat first.gz
# 當然同理我們可以通過zless,zmore來檢視
# zgrep需要查詢的字元用\-i引數指定,比如我想查詢帶有`line`字眼的內容:
zgrep -i line first.gz
# zdiff用來對比兩個歸檔檔案的不同,與diff類似
# 我們首先建立一個新的文字
echo "this second line">second
gzip second 
# 然後進行對比
zdiff first.gz second.gz
複製程式碼

”智慧“的Grep命令

黑技術:使grep具有與,或,非的邏輯

grep是我們經常使用的文字搜尋工具。那麼,我們如何使我們的grep具有與,或,非搜尋條件? 在介紹使用之前,我們先顯示我們要處理的資料(employee檔案)

100 張三 CEO 薪水 100k
101 李四 android工程師 薪水 10k
102 王五 IOS工程師 薪水 10k
103 劉六 Web工程師 薪水 20k
104 馮七 大資料工程師 薪水 25k
複製程式碼

grep並沒有直接的”與“命令,需要我們使用正規表示式來模擬與命令

grep -E "字元1.*字元2" filename
grep -E "字元1.*字元2|字元2.*字元1" filename
複製程式碼

我們要匹配要姓張,並且是CEO兩個條件。那麼,我們輸入的命令是:

grep -E "張.*CEO" employee
複製程式碼

我們要找文件中姓李與姓張的人: 方法1:

grep '字元1\|字元2' filename
複製程式碼
grep '張\|李' employee
複製程式碼

方法2:

grep -E '字元1|字元2' employee
複製程式碼
grep -E '張|李' employee
複製程式碼

除去所有姓李的人

grep -v '字元1' employee
複製程式碼
grep -v '李' employee
複製程式碼

回到過去的時光機

Linux 命令列黑技術(LTS)

黑技術1:靈活的Ctrl+R

日常開發工作的時候,我們經常遇到需要輸入大量類似的,重複的命令。那麼,我們能不能有一種方式可以根據幾個字母,找到以前輸入命令。方法當然是有的,就是Ctrl+R快捷鍵。

這裡通過例子來展示一下,如何使用Ctrl+R。 首先,使用history | tail -4來看下我們要用到的後四條歷史記錄:

1476  cd document
1477  ls
1478  service httpd stop
1479  cd /dev/cpu/ 
複製程式碼

情景一:重複歷史命令

如果,我想重新執行cd document命令,那麼,我需要輕敲鍵盤上的Ctrl+R鍵,然後,輸入cd就可以看到命令列自動將cd document填入到終端提示符後。這個時候只要輕敲回車,那麼,就可以復現命令。

# 按Ctrl+R鍵,然後,輸入cd
$bck-i-search:cd
# 下面為命令列自動補全的命令
$cd document
複製程式碼

情景二:在歷史命令的基礎上更改引數

這個步驟與場景一類似,當我們找到我們需要更改的命令,然後,按左鍵或者右鍵,退出搜尋模式,導航到我們需要修改的引數後,使用Ctrl+w刪除整個引數,修改即可。下面我用一個例子來解釋。這個例子是將1478 service httpd stopstop引數改為start

# 按Ctrl+R
$bck-i-search:service
# 找到相應的命令,然後按左,右導航鍵,退出搜尋模式
$ service httpd stop
# 然後我們按Ctrl-e到我們需要修改的stop引數後
$ service httpd stop
# 使用Ctrl+w刪除引數
$ service httpd 
# 補成我們需要的引數
$ service httpd start
複製程式碼

黑技術2:history 你不知道的事

讓 history 顯示時間戳

通過export HISTTIMEFORMAT='%F %T就可以讓history顯示時間戳。當然,你可以把這句話寫到你的.bashrc裡去,變成全域性配置。下面展示一下效果吧。

export HISTTIMEFORMAT='%F %T '
history | more
...
11  2018-04-19 12:54:15 zip STM32+HTTP/
12  2018-04-19 12:54:15 zip STM32+HTTP.zip STM32+HTTP/
13  2018-04-19 12:54:15 ;s
14  2018-04-19 12:54:15 man zip
15  2018-04-19 12:54:15 zip -r STMHTTP STM32+HTTP/
16  2018-04-19 12:54:15 ls
17  2018-04-19 12:54:15 mnt_entertain 
18  2018-04-19 12:54:15 cd_entertainment 
...
複製程式碼

注意不支援zsh,zsh的相關命令是HIS_STAMPS=dd-mm-yyyy

!回到過去的時光機

使用!的步驟:

  1. 通過history找到命令的序號,也就是history命令輸出前面的數字。
  2. 通過!前面得到的數字,然後,回車。就會將相應序號後面的命令補全到終端提示符後。

例子:

$history | head 
   10  2018-04-19 12:54:15 ls
   11  2018-04-19 12:54:15 zip STM32+HTTP/
   12  2018-04-19 12:54:15 zip STM32+HTTP.zip STM32+HTTP/
   13  2018-04-19 12:54:15 ;s
   14  2018-04-19 12:54:15 man zip
   15  2018-04-19 12:54:15 zip -r STMHTTP STM32+HTTP/
   16  2018-04-19 12:54:15 ls
   17  2018-04-19 12:54:15 mnt_entertain
   18  2018-04-19 12:54:15 cd_entertainment
   19  2018-04-19 12:54:15 ls
# 如果我想重複第17號命令,在終端提示符輸入!17然後按回車
$!17
$mnt_entertain
複製程式碼

去掉歷史記錄中重複的命令

export HISTCONTROL=ignoredups命令,就可以去除該命令以後的history記錄中的重複命令。這句話好像有點繞,下面我用例子來表示:

$export HISTCONTROL=ignoredups
$pwd
$pwd
$pwd
$history | tail -3
...
1111 pwd
...
複製程式碼

正如上例所示,我們輸入的3個pwd命令,最後,只剩下一個pwd命令,在我們的歷史記錄裡面。

將歷史命令的引數作為新命令的引數

場景一:當兩個命令相鄰時

Linux 命令列黑技術(LTS)
標題十分繞口。這裡直接上例子(注意#後面的是我對下面的命令做的解釋):

# 這裡我們使用cp命令來複制一個名為text的檔案
$cp text text.bak
# 我們想通過vim來編輯text.bak,只需要輸入vim !^
$vim !^
#下面這條命令是當我們輸入完上一條命令後,回車自動填充的內容
$ vim text.bak
# 我們想通過vim來編輯text,只需要輸入vim !!:$
$vim !!:$
#下面這條命令是當我們輸入完上一條命令後,回車自動填充的內容
$ vim text
複製程式碼
如果有多個引數

這裡假設有如下命令command1 arg1 arg2 arg3 arg4,我們需要在command2中使用command1一中的arg2引數,那麼我們如何用一種優雅的方式取到arg2引數?我們可以通過!!:2的方式取到,同理,如果,我們需要arg3引數,那麼可以通過!!:3,依次類推。

$command1 arg1 arg2 arg3 arg4
$command2 !!:2
#下面這條命令是當我們輸入完上一條命令後,回車自動填充的內容
$command2 arg2
$command2 !!:3
#下面這條命令是當我們輸入完上一條命令後,回車自動填充的內容
$command2 arg3
複製程式碼

場景二:當兩個命令不相鄰

如果,兩個命令不相鄰,當然也是有方法的。直接用例子來解釋吧。

$history|tail -3
...
command1 arg1 arg2 arg3 arg4
...
#我們的命令command2需要引數arg2
$command2 !command1:2
#下面這條命令是當我們輸入完上一條命令後,回車自動填充的內容
#command2 arg2
複製程式碼

wget強大的下載工具

Linux 命令列黑技術(LTS)

黑技術1:下載限速

下載限速,主要是用在多個任務環境。因為,我們常常需要在下載的同時做一些其他的事情。例如,瀏覽網頁。但是,wget命令預設開啟全速下載,這個時候,可能影響到我們其他的任務。所以,需要讓wget慢一點。wget通過--limit-rate來限制速度,舉個例子:

# 使用wget下載。並且,限制速度不超過200k。
wget --limit-rate=200k http://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-7/v7.0.86/bin/apache-tomcat-7.0.86-fulldocs.tar.gz
複製程式碼

黑技術2:後臺下載:

正(kai)常(che)的後臺下載。

wget -b http://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-7/v7.0.86/bin/apache-tomcat-7.0.86-fulldocs.tar.gz
複製程式碼

黑技術3:模擬瀏覽器請求

有些下載連結必須要通過瀏覽器下載,我們可以通過一些設定,讓wget的下載請求,像瀏覽器一般:

# URL-TO-DOWNLOAD是下載連結
wget --user-agent="Mozilla/5.0 (X11; Linux x86_64; rv:59.0) Gecko/20100101 Firefox/59.0" URL-TO-DOWNLOAD
複製程式碼

黑技術4:試探下載連結是否可以下載

我們有些時候需要知道這個連結是否可以下載,然後,対不同的情況作出判斷。

wget --spider http://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-7/v7.0.86/bin/apache-tomcat-7.0.86-fulldocs.tar.gz
複製程式碼

如果出現類似於下面的情況(最後以後顯示存在遠端檔案),那麼證明可以下載:

開啟 Spider 模式。檢查是否存在遠端檔案。
--2018-04-20 22:51:42--  http://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-7/v7.0.86/bin/apache-tomcat-7.0.86-fulldocs.tar.gz
正在解析主機 mirrors.tuna.tsinghua.edu.cn (mirrors.tuna.tsinghua.edu.cn)... 101.6.8.193, 2402:f000:1:408:8100::1
正在連線 mirrors.tuna.tsinghua.edu.cn (mirrors.tuna.tsinghua.edu.cn)|101.6.8.193|:80... 已連線。
已發出 HTTP 請求,正在等待迴應... 200 OK
長度:5162656 (4.9M) [application/octet-stream]
存在遠端檔案
複製程式碼

黑技術5:超過一定大小的檔案退出下載

下載檔案超過5MB,自動退出下載。

wget -Q5m 下載連結
複製程式碼

檔案列表“進化”

黑技術1:根據檔案大小從大到小(從小到大)顯示檔案

當前資料夾下從大到小排列

 find . -maxdepth 1 -type f -exec ls -s {} \; | sort -n -r
複製程式碼

我們可以把上面的命令使用alias寫入我們的.bashrc.zshrc,命名為ls_big

alias ls_big="find . -maxdepth 1 -type f -exec ls -s {} \; | sort -n -r"
複製程式碼

當前資料夾下從小到大排列

find . -maxdepth 1 -type f -exec ls -s {} \; | sort -n
複製程式碼

與上面一樣,我們可以寫道配置檔案裡

alias ls_small="find . -maxdepth 1 -type f -exec ls -s {} \; | sort -n"
複製程式碼

黑技術2:根據檔案的時間戳顯示檔案

這個需求,我們只需要使用ls -lt命令就可以來,當然,如果想要逆序輸出ls -ltr

黑技術3:檢視當前檔案所有的隱藏檔案和資料夾

檔案

find . -maxdepth 1 -type f -name ".*"
複製程式碼

我們可以寫到配置檔案中:

alias ls_file_hide="find .-maxdepth -type f -name ".*""
複製程式碼

資料夾

find . -maxdepth 1 -type d -name ".*"
複製程式碼

同理:

alias ls_file_hide="find .-maxdepth -type d -name ".*""
複製程式碼

相關文章