Bash空格的那點事

2022-09-22 22:21:18 字數 4943 閱讀 5615

bash空格的那點事

空格,乙個看不見的字元,很不起眼,也正由於不起眼,很多人經常忽略它,導致**出錯,卻還找不著北。這裡,我們來聊聊bash中空格的那點事。

先了解下bash中什麼時候該用空格,什麼時候不該用。

1. 等號賦值兩邊不能有空格

2. 命令與選項之間需要空格

3. 管道兩邊空格可有可無

我們來看看常見的問題

1. 賦值時等號兩邊或者只有左邊多了空格

igi@gentoo ~ $ var1 = test

bash: var1: command not found

igi@gentoo ~ $ echo $

bash: var1: error

igi@gentoo ~ $ echo $

bash: var1: error

igi@gentoo ~ $ var2 =test

bash: var2: command not found

igi@gentoo ~ $ echo $

bash: var2: error

igi@gentoo ~ $ echo $

bash: var2: error

這裡我用了bash的變數擴充套件,$當var1為unset或null(未定義或空)時, 報指定錯誤; $當var1為unset時,報指定錯誤 。從執行結果來看,如果等號左邊有空格,則變數名當成命令執行,結果報command not found,變數沒有被賦值

2. 賦值時等號左邊沒有空格,右邊有空格(這種情況有點特別,你會發現兩種情況)

igi@gentoo ~ $ var= test

igi@gentoo ~ $ var= nocmd

bash: nocmd: command not found

同樣是等號右邊有空格,第一條命令沒報錯,而第二條報錯了。

這是因為shell中有這麼一種執行命令的方式: var=string command

命令command將得到變數var的值(至於在命令執行後,變數var的值是否保留下來,bash4中沒有保留,但我在dash中發現時保留下來的,不同的shell對這個的處理不同), 由於test是個命令,而nocmd不是,所以報了command not found.

igi@gentoo ~ $ var=newtest eval echo \$var

newtest

igi@gentoo ~ $ echo $var

注意: 這裡我使用了eval, 是想避免在第一次解析時$var被替換成空字串, 不然就會出現下面的情況(下面是錯誤的測試方法,在echo還沒執行時,$var已經被替換成空字串)

igi@gentoo ~ $ var=newtest echo $var

igi@gentoo ~ $ echo $var

到這裡,相信大家都明白了吧, 對於等號賦值,左右兩邊不可以有空格,雖然右邊有空格不一定報錯,但那絕對不是你想要的結果。

3. 命令和選項之間必須有空格

這個似乎大家都明白,為何我還這麼羅嗦呢?說到這裡,不得不提一下乙個非常特別的命令: [ 命令(你沒看錯,是[ ), 也就是test命令(當然bash中,這是個內建命令,但在這裡不影響

我們的理解)。或許你會覺得[命令眼熟,沒錯,我保證你見過它,來看看下面的例子

igi@gentoo ~ $ if [ "abc" = "abc" ]; then echo 『they are the same』; fi

they are the same

igi@gentoo ~ $ type -a [

[ is a shell builtin

[ is /usr/bin/[

想起來了吧?[命令經常用到if判斷中,當然也有人喜歡這麼寫

igi@gentoo ~ $ [ "abc" = "cba" ] || echo 『they are not the same』

they are not the same

igi@gentoo ~ $ type -a [

[ is a shell builtin

[ is /usr/bin/[

[ 命令正名叫test命令,它們兩者幾乎一樣,為什麼不是完全一樣?來看看這個

igi@gentoo ~ $ [ "abc" = "cba"

bash: [: missing `]『

igi@gentoo ~ $ [ "abc" = "cba" ]

igi@gentoo ~ $ test "abc" = "cba" ]

bash: test: too many arguments

igi@gentoo ~ $ test "abc" = "cba"

清晰了吧,用[命令時,你必須給它個尾巴], 用test命令時,就不能加個尾巴。尾巴]是[最後乙個引數,不可缺少的引數, 代表[命令的結束

扯了這麼多,那到底這個和空格有毛關係?說這些,是先讓大家明白: [在shell中是個命令,它左右必須有空格!]是[的最後不可缺少的引數,它兩邊也需要空格(雖然有些命令的引數能連一起,例如ps, 但[命令不行,它的引數之間必須有空格)。讓我們看看關於[常見的錯誤

a. if 與 [ 之間缺少空格

igi@gentoo ~ $ if[ "$home" = "/home/igi"];then echo 'equal'; fi

bash: syntax error near unexpected token `then'

igi@gentoo ~ $ if[ "$home" = "/home/igi" ];then echo 'equal'; fi

bash: syntax error near unexpected token `then'

igi@gentoo ~ $ if["$home" = "/home/igi"];then echo 'equal'; fi

bash: syntax error near unexpected token `then'

igi@gentoo ~ $ if["$home" = "/home/igi" ];then echo 'equal'; fi

bash: syntax error near unexpected token `then'

語法分析錯誤,很明顯,if[ 對於bash來說,不知道是什麼鬼東西

b. [與後面的引數之間缺少空格

igi@gentoo ~ $ if ["$home" = "/home/igi" ];then echo 'equal'; fi

bash: [/home/igi: no such file or directory

igi@gentoo ~ $ if ["$home" = "/home/igi"];then echo 'equal'; fi

bash: [/home/igi: no such file or directory

["$home" 對於bash來說,也不知道是什麼鬼東西

c. [ ] 之間的引數之間缺少空格

igi@gentoo ~ $ if [ "abc"="abc" ]; then echo 'equal'; fi

equal

igi@gentoo ~ $ if [ "abc"="cba" ]; then echo 'equal'; fi

equal

第一條命令似乎是對的(實際上是正巧而已),看看第二條命令"abc" 和 "cba"明顯不同,但卻判斷為相同。這是因為引數之間缺少了空格,被[命令認為內部是個值而已。看看下面的命令,你就會釋然

igi@gentoo ~ $ if [ 0 ]; then echo 'equal'; fi

equal

igi@gentoo ~ $ if [ "1" ]; then echo 'equal'; fi

equal

igi@gentoo ~ $ if [ "" ]; then echo 'equal'; fi

igi@gentoo ~ $ if [ ]; then echo 'equal'; fi

在[ ] 內部,如果只有乙個值(那些因為缺少了空格而連一起的也算),不是空字串就為真。所以在[ ] 之間的引數,也要兩邊有空格,而不能堆一起

d. 引數和尾巴]之間缺少空格

這個就不羅嗦了,尾巴]也是[命令的引數,如同上面所講,引數之間必須有空格

扯了這麼多[命令與空格的事,但有些時候,缺了空格卻能正確執行, 當然這只是你好運, 一起來看看

igi@gentoo ~ $ var=' abc'

igi@gentoo ~ $ if [$var = "abc" ];then echo 'equal'; fi

equal

igi@gentoo ~ $ if ["$var" = "abc" ];then echo 'equal'; fi

bash: [ abc: command not found

之前bash引號那點事提到過,雙引號包圍起來的是乙個整體,而沒雙引號的時候,字串前後的空格或製表符都被切開。如果恰巧你遇到了或者你故意要丟棄字串前後的空格或製表符,那也不是不可能, 但非常不建議你這麼寫,你的**將是非常脆弱的。

或者你該加的空格都加了,但還是報錯,這也可能和缺少雙引號有關。這樣的情況很普遍,最後再看看

igi@gentoo ~ $ var=''

igi@gentoo ~ $ if [ "$var" = "abc" ];then echo 'equal'; fi

igi@gentoo ~ $ if [ $var = "abc" ];then echo 'equal'; fi

bash: [: =: unary operator expected

igi@gentoo ~ $ dvar='a b c'

igi@gentoo ~ $ if [ $dvar = "a b c" ];then echo 'equal'; fi

bash: [: too many arguments

igi@gentoo ~ $ if [ "$dvar" = "a b c" ];then echo 'equal'; fi

equal

我再羅嗦一次,不要輕易省略雙引號。

Shell程式設計 Bash引號的那點事

先了解下,在bash指令碼中,有三種引號 1.單引號 2.雙引號 3.反引號 單引號 兩個單引號包圍起來的字串就是普通的字串,它將保留原始的字面意思.雙引號 兩個雙引號包圍起來的字串,部分特殊字元將起到它們的作用.這些特殊字元有 美元符 反斜槓 反引號,感嘆號 反引號 兩個反引號包圍起來的字串,將作...

this的那點事

對於很多初學者,this總是搞得我們暈頭轉向。現在,我就簡單的總結一下關於this的那點事。this在函式定義時經常是不能確定的,只有在函式執行的時候才能最終確定this的歸屬。this總是指向最後呼叫它的物件,那麼怎麼知道到底是誰呼叫的呢?其實很簡單,我們知道函式呼叫的其中一種方法就是利用call...

bash下的空格

bash空格的那點事 空格,乙個看不見的字元,很不起眼,也正由於不起眼,很多人經常忽略它,導致 出錯,卻還找不著北。這裡,我們來聊聊bash中空格的那點事。先了解下bash中什麼時候該用空格,什麼時候不該用。1.等號賦值兩邊不能有空格 2.命令與選項之間需要空格 3.管道兩邊空格可有可無 我們來看看...