引用
在shell中,引用的意思就是時講字符串使用雙擁好括起來,他的作用就是保護字符串中的特殊字符、不被shell或者shell腳本重新解釋,或者擴展。
andrew@andrew:~$ ls -l [Ss]*
-rwx------ 1 andrew andrew 3849 1月 19 01:07 sources.list
andrew@andrew:~$ ls -l "[Ss]*"
ls: 無法訪問'[Ss]*': 沒有那個文件或目錄
andrew@andrew:~$
某些程序和工具能夠重新解釋或者擴展被引用的特殊字符,引用的一個重要的作用就是保護命令行參數不被shell解釋,但是還是能夠讓調用的程序來擴展它。
引用變量
在一個雙引號中通過直接使用變量名的方法來引用變量,一般情況下都是沒有問題的。這麼做將阻止所有在引號中的特殊字符被重新解釋 – 包括變量名 – 但是$
和\
除外。保持$
作爲特殊字符的意義是爲了能夠在雙引號中也能夠正常引用比變量,也就是說變量在雙引號中能夠被他的值所取代。
使用雙引號能夠阻止單詞分割,如果一個參數被雙引號括起來的話,那麼這個參數講認爲是一個單元,即使這個參數包含空白,那裏面的單詞也不會被分隔開。
# 定義一個變量
variable1="a variable containing five words"
# 在沒有雙引號的地方引用一個變量
COMMAND This is $variable1
# 用下面7個參數執行COMMAND命令:
# "This" "is" "a" "variable" "containing" "five" "words"
COMMAND "This is $variable1" # 用下面1個參數執行COMMAND命令:
# "This is a variable containing five words"
variable2=""
# Empty.
COMMAND $variable2 $variable2 $variable2
# COMMAND將不帶參數執行.
COMMAND "$variable2" "$variable2" "$variable2" # COMMAND將以3個空參數來執行.
COMMAND "$variable2 $variable2 $variable2"
# COMMAND將以1個參數來執行(2空格).
使用echo輸出一些詭異的變量
#!/bin/bash
# weirdvars.sh: echo出一些詭異變量.
var="'(]\\{}\$\""
echo $var
# '(]\{}$"
echo "$var"
# '(]\{}$"和上一句沒什麼區別.Doesn't make a difference.
echo
IFS='\'
echo $var
# '(] {}$"\ 字符被空白符替換了, 爲什麼?
# 雙引號下,IFS特殊字符不能被替換
echo "$var"
# '(]\{}$"
# 這個例子由Stephane Chazelas提供.
exit 0
執行結果
andrew@andrew:/work/bash/src$ bash echo_unique.sh
'(]\{}$"
'(]\{}$"
'(] {}$"
'(]\{}$"
單引號(’ ‘)操作與雙引號基本上一樣,但是不允許引用變量,因爲$的特殊意義被關閉了,在單引號中,任何特殊字符都按照字面的意思進行解釋,除了’ 。所以單引號(全引用)是一種比雙引號(雙引號)更嚴格的引用方法。
因爲即使是轉義字符(
\
)在單引號中也是按照字面意思解釋的,所以如果想在一對單引號中顯示一個單引號是不行的(因爲單引號的實現是按照就近原則完成的)。
echo "Why can't I write 's between single quotes"
echo
# 一種繞彎的方法.
echo 'Why can'\''t I write '"'"'s between single quotes'
#|-------| |----------||-----------------------|
# 三個被單引號引用的字符串, 在這三個字符串之間有一個用轉義符轉義的單引號, 和一個用雙引號括起來的單引號.
顯示單引號的兩種方法
- 將單引號放置在雙引號中
- 使用轉義字符
andrew@andrew:/work/bash/src$ bash single_quotation_mark.sh
Why can't I write 's between single quotes
Why can't I write 's between single quotes
在echo中雙引號中,使用!!的話,有可能會有意想不到的問題,因爲!!是歷史命令的意思,但是在腳本中使用!!沒有問題,因爲腳本中歷史命令是被禁止的
轉義
轉義是一種引用單個字符的方法,一個前面放上轉義字符(\
)的字符就是告訴shell這個字符按照字面的意思進行解釋,換句話說,就是這個字符失去了它的特殊含義。
在某些特殊的命令和工具中,比如echo和sed,轉義符往往會起到相反的效果 - 它反倒可能引發出這個字符的特殊含義。
特定轉義符的特殊的含義
echo
和sed
命令中使用
\n
- 表示新的一行
\r
- 表示回車
\t
- 表示水平製表符號
\v
- 表示垂直製表符
\b
- 表示後退符號
\a
- 表示alert
蜂鳴或者閃爍
\0xx
- 轉換爲八進制的ASCII
碼,等價於0xx
#!/bin/bash
# escaped.sh: 轉義符
echo; echo
echo "\v\v\v\v"
# 逐字的打印\v\v\v\v.
# 使用-e選項的'echo'命令來打印轉義符.
echo "============="
echo "VERTICAL TABS"
echo -e "\v\v\v\v"
# 打印4個垂直製表符.
echo "=============="
echo "QUOTATION MARK"
echo -e "\042"
# 打印" (引號, 8進制的ASCII 碼就是42).
echo "=============="
# 如果使用$'\X'結構,那-e選項就不必要了.
echo; echo "NEWLINE AND BEEP"
echo $'\n'
# 新行.
echo $'\a'
# 警告(蜂鳴).21
echo "==============="
echo "QUOTATION MARKS"
# 版本2以後Bash允許使用$'\nnn'結構.
# 注意在這裏, '\nnn\'是8進制的值.
echo $'\t \042 \t'
# 被水平製表符括起來的引號(").
# 當然,也可以使用16進制的值,使用$'\xhhh' 結構.
echo $'\t \x22 \t' # 被水平製表符括起來的引號(").
# 感謝, Greg Keraunen, 指出了這點.
# 早一點的Bash版本允許'\x022'這種形式.
echo "==============="
echo
# 分配ASCII字符到變量中.
# ----------------------------------------
quote=$'\042'
# " 被賦值到變量中.
echo "$quote This is a quoted string, $quote and this lies outside the quotes."
echo
# 變量中的連續的ASCII字符.
triple_underline=$'\137\137\137' # 137是八進制的'_'.
echo "$triple_underline UNDERLINE $triple_underline"
echo
ABC=$'\101\102\103\010'
# 101, 102, 103是八進制碼的A, B, C.
echo $ABC
echo; echo
escape=$'\033'
# 033 是八進制碼的esc.
echo "\"escape\" echoes as $escape"
#沒有變量被輸出.
echo; echo
exit 0
執行結果
andrew@andrew:/work/bash/src$ bash escape_charater.sh
# 在雙引號中的轉義符,將按照原樣輸出
\v\v\v\v
=============
VERTICAL TABS
==============
QUOTATION MARK
"
==============
NEWLINE AND BEEP
===============
QUOTATION MARKS
"
"
===============
" This is a quoted string, " and this lies outside the quotes.
___ UNDERLINE ___
ABC
"escape" echoes as
\"
表示引號字面意思
echo "hello" # hello
echo "\"hello\"" # "hello"
\$
- 輸出$
自身的意思
\\
表示反斜線字面意思
echo "foo
bar"
#foo
#bar
echo
echo 'foo
bar'
# 沒什麼區別.
#foo
#bar
echo
echo foo\
bar
# 換行符被轉義.
#foobar
echo
echo "foo\
bar"
# 與上邊一樣, \在部分引用中還是被解釋爲續行符.
#foobar
echo
echo 'foo\
bar'
# 由於是全引用, 所以\沒有被解釋成續行符.
#foo\
#bar