在Linux命令列下令人驚歎的驚歎號(!)
‘!’符號在Linux中不但可以用作否定符號,還可以用來從歷史命令記錄中取出命令或不加修改的執行之前執行的命令。下面的所有命令都已經在Bash Shell中經過確切地檢驗。儘管我沒有試過,但大多都不能在別的Shell中執行。這裡我們介紹下Linux命令列中符號’!'那驚人和奇妙的用法。
1. 使用數字從歷史命令列表中找一條命令來執行
您也許沒有意識到您可以從歷史命令列表(之前已經執行的命令集)中找出一條來執行。首先,通過”history”命令查詢之前命令的序號。
$ history
使用history命令找到最後執行的命令
現在,只需要使用歷史命令輸出中顯示在該命令前面的數字便可以執行這個命令。例如,執行一個在history輸出中編號是1551的命令。
$ !1551
使用命令ID來執行最後執行的命令
這樣,編號為1551的命令(上面的例子是top命令)便執行了。這種通過ID號來執行之前的命令的方式很有用,尤其是在這些命令都很長的情況下。您只需要使用![history命令輸出的序號]便可以呼叫它。
2. 執行之前的倒數第二個、第七個命令等
您可以以另一種方式來執行之前執行的命令,通過使用-1代表最後的命令,-2代表倒數第二個命令,-7代表倒數第七個命令等。
首先使用history命令來獲得執行過的命令的列表。history命令的執行很有必要,因為您可以通過它來確保沒有rm command > file或其他會導致危險的命令。接下來執行倒數第六個、第八個、第十個命令。
$ history $ !-6 $ !-8 $ !-10
通過負數序號執行之前執行的命令
3. 傳遞最後執行的命令的引數,以方便的執行新的命令
我需要顯示/home/$USER/Binary/firefox資料夾的內容,因此我執行:
$ ls /home/$USER/Binary/firefox
接下來,我意識到我應該執行’ls -l’來檢視哪個檔案是可執行檔案。因此我應該重新輸入整個命令麼?不,我不需要。我僅需要在新的命令中帶上最後的引數,類似:
$ ls -l !$
這裡!$將把最後執行的命令的引數傳遞到這個新的命令中。
將上一個命令的引數傳遞給新命令
4. 如何使用!來處理兩個或更多的引數
比如說我在桌面建立了一個文字檔案file1.txt。
$ touch /home/avi/Desktop/1.txt
然後在cp命令中使用絕對路徑將它拷貝到/home/avi/Downloads。
$ cp /home/avi/Desktop/1.txt /home/avi/downloads
這裡,我們給cp命令傳遞了兩個引數。第一個是/home/avi/Desktop/1.txt,第二個是/home/avi/Downloads。讓我們分別處理他們,使用echo [引數]來列印兩個不同的引數。
$ echo "1st Argument is : !^" $ echo "2nd Argument is : !cp:2"
注意第一個引數可以使用”!^”進行列印,其餘的命令可以通過”![命令名]:[引數編號]“列印。
在上面的例子中,第一個命令是cp,第二個引數也需要被列印。因此是”!cp:2″,如果任何命令比如xyz執行時有5個引數,而您需要獲得第四個引數,您可以使用”!xyz:4″。所有的引數都可以通過”!*”來獲得。
處理兩個或更多的引數
5. 以關鍵字為基礎執行上個的命令
我們可以以關鍵字為基礎執行上次執行的命令。可以從下面的例子中理解:
$ ls /home > /dev/null [命令1] $ ls -l /home/avi/Desktop > /dev/null [命令2] $ ls -la /home/avi/Downloads > /dev/null [命令3] $ ls -lA /usr/bin > /dev/null [命令4]
上面我們使用了同樣的命令(ls),但有不同的開關和不同的操作資料夾。而且,我們還將輸出傳遞到/dev/null,我們並未顯示輸出,因而終端依舊很乾淨。
現在以關鍵字為基礎執行上個的命令。
$ ! ls [命令1] $ ! ls -l [命令2] $ ! ls -la [命令3] $ ! ls -lA [命令4]
檢查輸出,您將驚奇發現您僅僅使用關鍵字ls便執行了您已經執行過的命令。
以關鍵字為基礎執行命令
(LCTT 譯註:澄清一下,這種用法會按照命令名來找到最後匹配的命令,不會匹配引數。所以上述執行的四個命令都是執行了 ls -lA /usr/bin > /dev/null,並增加了新的引數而已。)
6. !!操作符的威力
您可以使用(!!)執行/修改您上個執行的命令。它將附帶一些修改/調整並呼叫上個命令。讓我給您展示一些實際情境。
昨天我執行了一行指令碼來獲得我的私有IP,因此我執行了:
$ ip addr show | grep inet | grep -v 'inet6'| grep -v '127.0.0.1' | awk '{print $2}' | cut -f1 -d/
接著,我突然發現我需要將上面指令碼的輸出重定向到一個ip.txt的檔案,因此,我該怎麼辦呢?我該重新輸入整個命令並重定向到一個檔案麼?一個簡單的解決方案是使用向上游標鍵並新增’> ip.txt’來將輸出重定向到檔案。
$ ip addr show | grep inet | grep -v 'inet6'| grep -v '127.0.0.1' | awk '{print $2}' | cut -f1 -d/ > ip.txt
在這裡要感謝救世主”向上游標鍵”。現在,考慮下面的情況,這次我執行了下面這一行指令碼。
$ ifconfig | grep "inet addr:" | awk '{print $2}' | grep -v '127.0.0.1' | cut -f2 -d:
一旦我執行了這個指令碼,Bash提示符便返回了錯誤訊息”bash: ifconfig: command not found”。原因並不難猜,我執行了本應以root許可權的執行的命令。
所以,怎麼解決呢?以root使用者登入並且再次鍵入整個命令就太麻煩了!而且向上導航鍵也不管用了(LCTT 譯註:當你以新的使用者身份登入了,是不能用向上游標鍵找到之前的另外一個使用者的命令歷史的)。因此,我們需要呼叫”!!”(去掉引號),它將為那個使用者呼叫上個命令。
$ su -c !! root
這裡su是用來切換到root使用者的,-c用來以某使用者執行特定的命令,最重要的部分是!!,它將被替換為上次執行的命令。當然!您需要提供root密碼。
!!操作符的威力
我通常在下面的情景中使用!!。
當我用普通使用者來執行apt-get,我通常收到提示說我沒有許可權來執行。
$ apt-get upgrade && apt-get dist-upgrade
好吧,有錯誤。但別擔心,使用下面的命令來成功的執行…
$ su -c !!
同樣的適用於:
$ service apache2 start
或
$ /etc/init.d/apache2 start
或
$ systemctl start apache2
普通使用者不被授權執行那些任務,這樣相當於我執行:
$ su -c 'service apache2 start'
或
$ su -c '/etc/init.d/apache2 start'
或
$ su -c 'systemctl start apache2'
(LCTT 譯註:使用!!之前,一定要確認你執行的是什麼命令!另外,在 root 身份下,千萬不要養成使用它的習慣,因為你總是會在不合適的目錄執行不合適的命令!)
7.執行一個影響所有除了![FILE_NAME]的檔案命令
!(邏輯非)能用來對除了’!'後的檔案的所有的檔案/副檔名執行命令。
A.從資料夾移除所有檔案,2.txt除外。
$ rm !(2.txt)
B.從資料夾移除所有的檔案型別,pdf型別除外。
$ rm !(*.pdf)
8.檢查某個資料夾(比如/home/avi/Tecmint)是否存在?並列印
這裡,我們使用’! -d’來驗證資料夾是否存在,當資料夾不存在時,將使用其後跟隨AND操作符(&&)進行列印,當資料夾存在時,將使用OR操作符(||)進行列印。
邏輯上,當[ ! -d /home/avi/Tecmint ]的輸出為0時,它將執行AND邏輯符後面的內容,否則,它將執行OR邏輯符(||)後面的內容。
$ [ ! -d /home/avi/Tecmint ] && printf '/nno such /home/avi/Tecmint directory exist/n' || printf '/n/home/avi/Tecmint directory exist/n'
9.檢查某資料夾是否存在?如果不存在則退出該命令
類似於上面的情況,但這裡當期望的資料夾不存在時,該命令會退出。
$ [ ! -d /home/avi/Tecmint ] && exit
10.如果您的home資料夾內不存在一個資料夾(比方說test),則建立它
這是指令碼語言中的一個常用的實現,當期望的資料夾不存在時,建立一個。
[ ! -d /home/avi/Tecmint ] && mkdir /home/avi/Tecmint
這便是全部了。如果您知道或偶爾遇到其他值得了解的’!'使用方法,請您在反饋的地方給我們提建議。保持聯絡!
相關文章
- 20個令人驚歎的桌面Docker容器Docker
- 幾個令人驚歎的函式影象函式
- 12個令人驚歎的CSS實驗專案CSS
- 那些令人驚歎的 HTML、CSS、JavaScript 工具和庫HTMLCSSJavaScript
- 10個令人驚歎的HTML5和JavaScript效果HTMLJavaScript
- ES13中11個令人驚歎的 JavaScript 新特性JavaScript
- 創造令人驚歎的遊戲關卡——從構圖開始遊戲
- 9款令人驚歎的HTML5 3D動畫應用HTML3D動畫
- Linux 命令列小技巧 – !歎號的用處Linux命令列
- 令人驚歎的百度Echarts,大資料分析的必備工具Echarts大資料
- 7個讓你驚歎的HTML技巧HTML
- Webpack5構建速度提升令人驚歎,早升級早受益Web
- 《路易吉鬼屋3》:將令人驚歎的創意設計在遊戲的各個細節遊戲
- 關於Linux中“!”你不知道的驚歎用法Linux
- 開發者談失敗:有很多令人驚歎的故事卻沒有成功的結局
- 7 個讓人驚歎的 HTML5 滑鼠動畫HTML動畫
- 重溫《殺手》:高自由度開放式關卡設計,令人驚歎的動態遊戲世界遊戲
- 7款讓人驚歎的HTML5粒子動畫特效HTML動畫特效
- Apple推出了令人驚歎的耳掛式設計AirPods Max,這是AirPods的魔力APPAI
- JavaScript兩個歎號(!!)JavaScript
- 下一代 CLI 工具,使用Go語言用於構建令人驚歎的網路應用程式Go
- 驚歎!這個盲人程式設計師是這樣寫程式碼的程式設計師
- 令程式設計師驚歎的一些CSS3效果庫程式設計師CSSS3
- 用萌寵去突破!這款新遊的大世界讓人驚歎
- javascript兩個歎號!!的作用是什麼JavaScript
- 2024.7 #2 幻想現實交映輝耀 朝向命運刻下驚歎號 要我 的驕傲 隨生命喧囂
- 這些JavaScript程式設計黑科技,裝逼指南,高逼格程式碼,讓你驚歎不已JavaScript程式設計
- 《意航員 2》GI 評測 9 分:每分每秒都令人讚歎
- 15個令人震驚的HTML5實驗HTML
- javascript兩個!歎號一起使用的作用是什麼JavaScript
- 一個令人驚豔的ChatGPT專案,開源了!ChatGPT
- 10個這些年令人驚訝的技術革新
- 11個讓你吃驚的Linux終端命令Linux
- 11 個讓你吃驚的 Linux 終端命令Linux
- 11個讓你吃驚的 Linux 終端命令Linux
- 利用CSS變數實現令人震驚的懸浮效果CSS變數
- 總結28個令人驚豔的JavaScript單行程式碼JavaScript行程
- 數學與軟體工程那些令人驚訝的相似性軟體工程