bash-shell高級編程--引用

引用

在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'
#|-------| |----------||-----------------------|
# 三個被單引號引用的字符串, 在這三個字符串之間有一個用轉義符轉義的單引號, 和一個用雙引號括起來的單引號.

顯示單引號的兩種方法

  1. 將單引號放置在雙引號中
  2. 使用轉義字符
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,轉義符往往會起到相反的效果 - 它反倒可能引發出這個字符的特殊含義。

特定轉義符的特殊的含義

echosed命令中使用

\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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章