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
发布了369 篇原创文章 · 获赞 148 · 访问量 33万+

猜你喜欢

转载自blog.csdn.net/andrewgithub/article/details/104108028