Linux命令行下感嘆號的幾個用法

Linux命令行下 " ! " 的幾個用法

! 在大多數編程語言中表示取反的意思,但是在命令行中,他還有一些其他的神奇用法。熟練掌握這些用法,可以大大提高我們日常命令行操作的效率。

1 執行歷史命令

!!

! 在命令行中可以用來執行歷史命令,最常用的,大家應該比較熟悉的是執行上一條命令 !!,它可以用來執行最近的一條命令

該命令在我們忘記使用 root 權限執行某項命令時很有用:sudo !! 在上一條命令之前加 root 權限再執行。

比如,我們要用 fdisk 命令查看磁盤信息,但是如果沒有 root 權限是會被拒絕的,這時我們就可以直接 sudo !!

$ fdisk -l
fdisk: cannot open /dev/loop0: Permission denied
# ...
fdisk: cannot open /dev/loop30: Permission denied
fdisk: cannot open /dev/loop31: Permission denied
$ sudo !!
sudo fdisk -l
[sudo] password for song:
Disk /dev/loop0: 4.2 MiB, 4448256 bytes, 8688 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
# ...

或者在我們忘記加某項參數時,也可以通過 !! -p 來快速添加參數執行上一條命令。比如我要 gdb 調試某個源文件,但是忘了加 -g 參數,即可:

g++ quickSort.cpp
!! -g

有趣的是,!! 符號可以理解為完整地重復上一條指令的文本,即使在有些時候語義不連貫也是可行的。比如下面這個情景。

在當前目錄下,我們有 tsne.py 和 tsne.png 兩個文件,這時我想要 vim 修改 tsne.py 的內容,很有可能會手快通過 tab 鍵執行這樣的命令:vim tsne.p,這時我們可以直接 !!y,就能順利地執行 vim tsne.py

!n

!! 命令雖然很好用,但是它只能執行上面最近一條命令,那么能不能執行上面幾條(如倒數第二條、倒數第三條)指令呢,又能不能有一個一般的命令,來執行某一條歷史命令呢?當然是有的!

首先,我們知道 history 命令可以查看最近的歷史命令。值得注意的是,它顯示的每條歷史命令之前會有一個編號,我們好像在平常沒太注意過這個編號有什么作用:

$ history2083  ls2084  vim quickSort.cpp2085  g++ quickSort.cpp2086  g++ quickSort.cpp  -g2087  history

實際上,我們可以直接通過這個編號來執行某條歷史命令,如 !2084

這個用法好像比較雞肋,因為歷史命令編號我們很少回去記住它,每次要用 history 命令查,再執行的話未免有些麻煩。筆者一時能想到的應用場景是如果我們在一段時間(比如一小時、一下午)內,要重復的用某條超復雜的命令(比如很長的路徑名),我們不妨短時記憶一下某個歷史命令編號,并多次使用該編號執行歷史命令。

比如我今天下午調試程序時要多次修改某個 py 文件,就可以記住這個命令的編號,然后每次 !1994 來執行歷史命令。

 1994  vim /home/ps/JJ_Projects/ssl_transformer_aes/my_project/SiT/pretrain_ssl.sh

!-i

!-i 的形式可以執行倒數第 i 條命令。如 !-6!-8等。特別地,!-1 就相當于 !!

!cmd

!cmd 通過關鍵詞來執行歷史命令。可以按照下面的命令來理解:

$ ls /home > /dev/null
$ ls -l /home/song/JJ_Projects/ > /dev/null
$ ls -la /home/song/JJ_Projects/ > /dev/null
$ ls -lA /usr/bin > /dev/null

上面是相同的ls命令對應了不同參數和文件夾。此外我們將每一個標準輸出都傳遞到了 /dev/null 因為我們并不希望處理程序的標準輸出。現在我們可以調用命令的關鍵詞來實現它們。

$ !ls
$ !ls -l
$ !ls -la
$ !ls -lA

當你使用 !ls 關鍵詞來執行之前命令的時候,你一定會被標準輸出給驚訝到。

2 復用歷史參數

!$和!^

如同 !! 來執行上一條命令一樣,!$!^ 也是很常用的,它們的作用是重復上一條命令的第一個或最后一個參數

!$ 為例,考慮這樣的場景,我要刪除某個目錄下的所有 png 圖像文件,但是在刪除之前,我要先查看一下,確定這些圖像文件確實都是沒有用的。可以這樣操作:

ls /home/song/JJ_Projects/ava-mlsp/metadata/*.png
rm !$

這樣能省去我們重復上一個命令操作參數的時間。

另一個更普遍的場景:當我們編輯完 ~/.bashrc 文件后,需要用 source 命令使它生效,此時可以:

vim ~/.bashrc
# 一頓操作,修改 .bashrc 文件內容
source !$

!cmd:n

同樣的,我們將 !$!^ 推廣到一般情況,!cmd:n :獲取最近一次 cmd 命令的第 n 個參數(參數的個數從 0 開始計)。

如:

ls -a -l
ls !ls:1 	

這樣后面一條命令相當于執行了:ls -l

3 取反

! 在很多編程語言中都是取反的意思,!= 也通常都是不等于的意思。

在邏輯判斷中取反

同大多數編程語言一樣,! 在 shell 腳本中表示取反的意思。

[ ! -d /home/song/JJ_Prjects ] 可以用來判斷該目錄是否為空。

在命令中取反

rm !(train.py) 可以刪除當前目錄下除了 train.py 之外的全部文件。rm !(*.png) 刪除當前目錄下除了后綴名為 png 之外的全部文件。

總結起來最常用的除了在編程時取反之外,在命令行中用起來比較絲滑的也就是 !!!$,它們的推廣的更一般的形式雖然能實現的功能更全面,但稍顯麻煩,不太常用。以上就是筆者對 ! 在命令行中使用的總結了,如果有錯誤或補充,歡迎留言討論。

Ref:

https://linuxstory.org/mysterious-ten-operator-in-linux/

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/532652.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/532652.shtml
英文地址,請注明出處:http://en.pswp.cn/news/532652.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

三地址碼簡介

三地址碼簡介 三地址碼(Three Address Code)是一種最常用的中間語言,編譯器可以通過它來改進代碼轉換效率。每個三地址碼指令,都可以被分解為一個四元組(4-tuple)的形式:(運算符&am…

llvm與gcc

llvm與gcc llvm 是一個編譯器,也是一個編譯器架構,是一系列編譯工具,也是一個編譯器工具鏈,開源 C11 實現。 gcc 相對于 clang 的優勢: gcc 支持更過語言前端,如 Java, Ada, FORTRAN, Go等gcc 支持更多地 …

攻防世界web新手區解題 view_source / robots / backup

1**. view_source** 題目描述:X老師讓小寧同學查看一個網頁的源代碼,但小寧同學發現鼠標右鍵好像不管用了。 f12查看源碼即可發現flag 2. robots 題目描述:X老師上課講了Robots協議,小寧同學卻上課打了瞌睡,趕緊來教教…

python參數傳遞*args和**kwargs

python參數傳遞*args和**kwargs 和* 實際上真正的Python參數傳遞語法是 * 和 ** 。*args 和 **kwargs 只是一種約定俗成的編程實踐。我們也可以寫成 *vars 和 **kvars 。就如同其他常規變量的命名一樣, args 和 kwargs 只是一種習慣的名稱。 *args 和 **kwargs 一…

聽GPT 講Rust源代碼--src/tools(25)

File: rust/src/tools/clippy/clippy_lints/src/methods/suspicious_command_arg_space.rs 在Rust源代碼中,suspicious_command_arg_space.rs文件位于clippy_lints工具包的methods目錄下,用于實現Clippy lint SUSPICIOUS_COMMAND_ARG_SPACE。 Clippy是Ru…

Java一次編譯,到處運行是如何實現的

Java一次編譯,到處運行是如何實現的 轉自:https://cloud.tencent.com/developer/article/1415194 (排版微調) JAVA編譯運行總覽 Java是一種高級語言,要讓計算機執行你撰寫的Java程序,也得通過編譯程序的…

JIT(動態編譯)和AOT(靜態編譯)編譯技術比較

JIT(動態編譯)和AOT(靜態編譯)編譯技術比較 轉自:https://www.cnblogs.com/tinytiny/p/3200448.html Java 應用程序的性能經常成為開發社區中的討論熱點。因為該語言的設計初衷是使用解釋的方式支持應用程序的可移植…

python解釋器

python解釋器 計算機編程語言 本部分參考自:https://zhuanlan.zhihu.com/p/141212114 從計算機編程語言說起,它主要分為三類:機器語言、匯編語言、高級語言。 機器語言是一種計算機可以直接識別并執行的二進制指令集。由于其可以直接交給…

編譯型語言與解釋型語言

編譯型語言與解釋型語言 首先要說明,編譯型語言與解釋型語言這種分類方法是不科學的,或者說已經過時了,但是這種稱呼大抵還是能夠讓人明白我們將要討論的是什么東西。 文中所列參考是筆者認為比較有幫助的一些擴展閱讀內容。 首先貼一個很形…

常見的各種shell及其區別

常見的各種shell及其區別 引子 for((i1;i<10;i)); do echo $(expr $i \* 3 1); done 網上搜到的 shell for循環腳本&#xff0c;別人都能正常運行&#xff0c;我卻報錯&#xff1a; Syntax error: Bad for loop variable究竟是怎么回事呢&#xff1f; shell簡介…

shell腳本 變量

shell腳本 變量類型 什么是Shell變量 用一個固定的字符串去表示不固定的內容。 Shell變量的類型 shell腳本中自定義變量的類型&#xff0c;我們這里分為&#xff1a; 自定義變量環境變量位置變量與定義變量 這四類&#xff0c;它們有一些相同點&#xff0c;但又有些不同點…

攻防世界web新手區解題 /cookie / disabled_button / weak_auth

cookie 題目描述&#xff1a;X老師告訴小寧他在cookie里放了些東西&#xff0c;小寧疑惑地想&#xff1a;‘這是夾心餅干的意思嗎&#xff1f;’ 使用burp suite抓包查看 發現提示&#xff1a; look-herecookie.php 于是在url后加上 cookie.php 得到提示查看返回 就得到了f…

Python 函數式編程

Python 函數式編程 轉自&#xff1a;https://www.liaoxuefeng.com/wiki/1016959663602400/1017328525009056&#xff0c;推薦去該鏈接讀原文&#xff0c;有習題和熱烈的評論區交流。 函數式編程 函數是Python內建支持的一種封裝&#xff0c;我們通過把大段代碼拆成函數&…

Python中的生成器與迭代器

Python中的生成器與迭代器 轉自&#xff1a;https://www.liaoxuefeng.com/wiki/1016959663602400/1017323698112640&#xff0c;推薦去該鏈接讀原文&#xff0c;有習題和熱烈的評論區交流。 生成器 通過列表生成式&#xff0c;我們可以直接創建一個列表。但是&#xff0c;受…

基于GET報錯的sql注入,sqli-lab 1~4

根據注入類型可將sql注入分為兩類&#xff1a;數字型和字符型 例如&#xff1a; 數字型&#xff1a; sleect * from table where if 用戶輸入id 字符型&#xff1a;select * from table where id 用戶輸入id &#xff08;有引號) 通過URL中修改對應的D值&#xff0c;為正常數字…

Python 裝飾器詳解(上)

Python 裝飾器詳解&#xff08;上&#xff09; 轉自&#xff1a;https://blog.csdn.net/qq_27825451/article/details/84396970&#xff0c;博主僅對其中 demo 實現中不適合python3 版本的語法進行修改&#xff0c;并微調了排版&#xff0c;本轉載博客全部例程博主均已親測可行…

xss原理和注入類型

XSS漏洞原理 : XSS又叫CSS(cross Site Script), 跨站腳本攻擊,指的是惡意攻擊者往Web頁面里插入惡意JS代碼,當用戶瀏覽該頁時,嵌入其中的Web里的JS代碼就會被執行,從而達到惡意的特殊目的. 比如:拿到cooike XSS漏洞分類: 反射性(非存儲型) payload沒有經過存儲,后端接收后,直接…

Python 裝飾器詳解(中)

Python 裝飾器詳解&#xff08;中&#xff09; 轉自&#xff1a;https://blog.csdn.net/qq_27825451/article/details/84581272&#xff0c;博主僅對其中 demo 實現中不適合python3 版本的語法進行修改&#xff0c;并微調了排版&#xff0c;本轉載博客全部例程博主均已親測可行…

存儲型xss案例

存儲型xss原理: 攻擊者在頁面插入xss代碼,服務端將數據存入數據庫,當用戶訪問存在xss漏洞的頁面時,服務端從數據庫取出數據展示到頁面上,導致xss代碼執行,達到攻擊效果 案例: 在一個搭建的論壇網站中, 根據存儲型xss注入的條件,要找到可以存儲到數據庫的輸入位置,并且這個位置…

反射型XSS案例

**原理:**攻擊者將url中插入xss代碼,服務端將url中的xss代碼輸出到頁面上,攻擊者將帶有xss代碼的url發送給用戶,用戶打開后受到xss攻擊 需要url中有可以修改的參數 案例: 可能存在反射型xss的功能(點) : 搜索框等&#xff08;所有url會出現參數的地方都可以嘗試&#xff09;……