【shell】—双引号引用变量


一、举例—单、双引号引用变量的结果差异

1、运行下面代码:

time_tag="2022050912"  
outFileName='newnbr_raoming_model.${time_tag}.txt'
echo $time_tag,$outFileName

运行结果:

2022050912,newnbr_raoming_model.${time_tag}.txt

观察运行结果,可以发现outFileName变量中引用的time_tag变量名没有赋值2022050912,而是直接输出了,这不是我们想要的。

time_tag="2022050912"  
outFileName="newnbr_raoming_model.${time_tag}.txt"
echo $time_tag,$outFileName

2、解决方法:引用outFileName变量时,将单引号变成双引号,发现outFileName变量中引用的time_tag变量名成功赋值为2022050912。

time_tag="2022050912"  
outFileName="newnbr_raoming_model.${time_tag}.txt"
echo $time_tag,$outFileName

运行结果:

2022050912,newnbr_raoming_model.2022050912.txt

3、原因:单引号(’ ')与双引号类似,但是单引号中不能引用变量,因为$不再具有特殊含义。在单引号中,除 '(单引号)之外的所有特殊字符都将会被直接按照字面意思解释。可以认为单引号(全引用)是双引号(部分引用)的一种更严格的形式。


二、使用双引号引用变量的场景

引用变量时,通常建议将变量包含在双引号中,这样可以防止除 $,`(反引号),\ (转义符)之外的其他特殊字符被重新解释。(在双引号之中, $代表引用变量的值,而 ` (反引号)代表引用命令,\ (转义符)可以保留字符字面输出,主要针对$、`、\ 这三个在双引号有特殊含义的字符。)

1、使用双引号—可以防止字符串被分割

举例1:

运行下面代码:

List="one two three"

for a in $List #空白符将变量分成几个部分
do 
	echo $a
done

运行结果:

one
two
three

空白符将变量分成几个部分。

变量加上双引号,运行下面代码:

List="one two three"

for a in "$List" #在单一变量中保留所有空格
do 
	echo $a
done

运行结果:

one two three

2、使用双引号—特殊字符变为普通字符

举例1:

运行下面代码:

#!/bin/bash
# test.sh: 输出一些奇怪的变量

var="'(]\\{}\$\""
echo $var      
echo "$var"    

运行结果:

'(]\{}$"
'(]\{
    
    }$"

echo $var 与echo “$var” 的运行结果没有区别。

举例2:

运行下面代码:

IFS='\' #定义分隔符
var="'(]\\{}\$\""
echo $var      
echo "$var" 

运行结果:

'(] {}$"
'(]\{
    
    }$"

echo $var 的运行结果中 \ 直接被转换成空格了,echo “$var” 的运行结果没有任何区别。

举例3:

运行下面代码:

var1="Have I Told You Lately That I Love You"
echo "\$var1 = "$var1""    

运行结果:

$var1 = Have I Told You Lately That I Love You

双引号中,单独的$表示引用变量,如果$想要单纯按照字面意思输出,加上转义符号(\)。

3、使用双引号—保存原始命令的输出格式

举例1:

运行下面代码:

echo "$(echo '"')"

运行结果:

"

举例2:

运行下面代码:

echo $(cal)
echo "$(cal)"

运行结果:

July 2024 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

      July 2024     
Su Mo Tu We Th Fr Sa
    1  2  3  4  5  6
 7  8  9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31

如果$(cal)不放在双引号之中,echo就会将所有结果以单行输出,丢弃了所有原始的格式。

4、使用双引号—具有强约束的单引号变为普通单引号字符

两个单引号之间不能使用单引号,在单引号中转义符(\)都已经按照字面意思解释。所以要想打印单引号,要用双引号。

举例:

运行下面代码:

echo "Why can't I write 's between single quotes"

运行结果:

Why can't I write 's between single quotes

举例: 单引号具有强约束力,在单引号中转义符(\)都已经按照字面意思解释。

运行下面的代码:

var3='\\\\'
echo $var3 
echo "$var3"

运行结果:

\\\\
\\\\

5、注意

1、双引号中转义符会被解释,并按照其含义进行替换。
如果在$、`、\ 这三个字符前面,就是转义符的意思,如果在其他字符前面,则不需要解释,直接输出\与其他字符。

举例1:

运行下面代码:

echo \
echo "\"

执行上面两个语句,都会出现>的符号,意思是等待继续的输入。

举例2:

运行下面代码:

echo \a
echo "\a" 

运行结果:

a
\a

举例3:

运行下面代码:

echo x\ty
echo "x\ty"

运行结果:

xty
x\ty

举例3: 注意 echo -e 会将 “\t” 解释成制表符。

运行下面代码:

echo -e  x\ty
echo -e "x\ty"

运行结果:

xty
x       y

2、双引号包含了 “!” 将会产生错误,这是因为shell将其解释为查看历史命令。
而在脚本中,因为历史机制已经被关闭,所以不会产生这个问题。

举例:

运行下面代码:

echo "hello!"

运行结果:
-bash: !": event not found

运行下面代码:

echo "hello\!"

运行结果:

hello\!

参考文章:
引用变量
shell中的引号和转义