Bash 中為 變數賦空值的三個場景

2021-09-07 02:17:03 字數 1512 閱讀 8956

$_ 有好幾個功能,我們最常用的是用它來獲取「剛剛執行過的命令的最後乙個引數」這個功能,比如下面這樣:

$ ls ~/downloads/very/long/dir/  # ls 到某個目錄看看有沒有我們想要的檔案

file1 file2 needed_file

$ cd $_ # 如果有,就進入到那個資料夾,$_ 讓你省去了不少鍵盤敲擊數  

bash manual 中對 $_ 的這個功能的描述只有一句話:

expands to the last argument to the previous command, after expansion.

惜字如金,讓你覺的這個功能真的很簡單,但稍微深入想一想,如果上次執行的命令完全沒有引數呢?

$ echo # 沒有引數

$ echo $_

echo

哦哦,這下我們知道了,如果乙個引數也沒有,那麼 $_ 就是命令的名字本身。那麼問題又來了,如果命令的名字也沒有呢?有些同學就問了,怎麼寫出乙個連命令名也沒有的命令呢。其實在 shell 裡面,一條簡單命令的組成文法大概是這個樣子的:

賦值語句 命令名和引數 重定向

比如 foo=1 bar baz >qux 就是三個部分都存在的命令,但其實,這個三個部分只要存在乙個部分就算是一條簡單命令了,不信我們試試:

$ foo=1 # 只有第一部分,這也是一條命令,很熟悉吧,就是我們常見的賦值語句

$ foo=1 > bar # 沒有第二部分,這也可以

$ >bar # 只有第三部分,還可以

下面就說結論了:當沒有命令名和引數這一部分的時候,bash 會給 _ 賦空值:

$ : foo

$ echo $_ # _ 的值是 foo

foo$ foo=1

$ echo "左邊$_右邊" # _ 的值被 bash 賦值為空,這種情況在 zsh 下只是不更新 _ 的值,還是 foo,但不會賦空值

左邊右邊

$ : foo

$ > bar

$  echo "左邊$_右邊" # 同樣,又被賦值為空,zsh 下還會是 foo

左邊右邊

除了這種沒有命令名和引數的場景,還有兩種情況下 bash 會給 _ 賦空值,乙個是包含管道的命令,再乙個是後台(非同步)執行的命令:

$ : foo

$ echo 1 | echo 2

$ echo "左邊$_右邊" # _ 為空,在 zsh 下會是最後乙個管道右邊的命令的最後乙個引數,也就是 2

左邊右邊

$ echo 1 &

$ echo "左邊$_右邊" # _ 還是空,在 zsh 下沒有特殊處理,是 1

左邊右邊

還有乙個 bash 文件沒明確指出的點,那就是只有簡單命令才會更新 _ 的值,管道命令,命令列表,復合命令這些命令本身,都不會更新 _ 的值,但它們包含的簡單命令要是執行了的話是會影響的(比如 for 迴圈裡的簡單命令沒有執行的話,不會更新 _,反之亦然)。

交換兩個變數的值,不使用第三個變數

通常我們的做法是 尤其是在學習階段 定義乙個新的變數,借助它完成交換。如下 int a,b a 10 b 15 int t t a a b b t 這種演算法易於理解,特別適合幫助初學者了解電腦程式的特點,是賦值語句的經典應用。在實際軟體開發當中,此演算法簡單明瞭,不會產生歧義,便於程式設計師之間的...

不借助第三個變數交換兩個變數的值

通常我們的做法是 尤其是在學習階段 定義乙個新的變數,借助它完成交換。如下 int a,b a 10 b 15 int t t a a b b t 這種演算法易於理解,特別適合幫助初學者了解電腦程式的特點,是賦值語句的經典應用。在實際軟體開發當中,此演算法簡單明瞭,不會產生歧義,便於程式設計師之間的...

如何實現兩個變數的值交換,輸出三個值的最大值

例題 var a 123 var b 234 請使用任意方法交換a和b的值。方法一 定義中間變數 var c c a a b b c 方法二 和方法 兩數之和,和減去其中乙個數,得到的結果為另乙個數 a a b b a 方法三 差方法 兩數之差,被減數減去差,就得到乙個減數 減數加上差就得被減數 a...