shell高级编程笔记(第五章 引用(引号))

第五章 引用(引号)

引号的特殊效果就是保护字符串中的特殊字符不被shell或shell脚本重新解释或者扩展。
(这里所说的"特殊"指的是一些字符在shell中具有特殊的意义,比如:*)

[root@localhost aaa]# ls
1.sh  2.txt  file.txt  File.txt
[root@localhost aaa]# ls [Ff]*
file.txt  File.txt

[root@localhost aaa]# ls '[Ff]*'
ls: 无法访问[Ff]*: 没有那个文件或目录

特定的程序和工具能够重新解释或者扩展特殊的字符。引号的一个重要的作用就是保护命令行的参数,但还是允许正在调用的程序来扩展它

grep '[Ff]irst' *.txt
file1.txt:This is the first of file1.txt
file2.txt:This is the First of file2.txt    

#grep [Ff]irst *.txt   在Bash下的行为也是这样(正则)

引号还可以抑制echo命令的换行作用

[root@localhost aaa]# echo $(ls -l)
总用量 4 -rwxr-xr-x 1 root root 64 5月 28 01:57 1.sh -rw-r--r-- 1 root root 0 6月 22 18:38 2.txt

[root@localhost aaa]# echo "$(ls -l)"
总用量 4
-rwxr-xr-x 1 root root 64 5月  28 01:57 1.sh
-rw-r--r-- 1 root root  0 6月  22 18:38 2.txt

5.1 引用变量

在一个双引号中直接使用变量名一般都是没有问题的。它阻止了所有在引号中的特殊字符的重新解释(包括变量名),但是$、`和\除外。
$ 作为特殊字符的意义,是为了能够在双引号中也能正常地引用变量。这样在""中可以使用变量表达式的值(Example 4.1)

使用""来防止单词分割。如果在参数列表中使用双引号,将使得双引号中的参数作为一个参数。即使双引号中的字符串包含多个单词,也不会边为多个参数。如:

variable1="a variable containing five words"
COMMAND This is $variable1   #COMMAND将以7个参数来执行
#"This" "is"  "a" "variable" "containing" "five" "words"

COMMAND "This is $variable1"   #COMMAND将以1个参数来执行
#"This is a variable containing five words"

variable2=""
COMMAND $variable2 $variable2 $variable2   #COMMADN将不带参数执行
COMMAND "$variable2" "$variable2" "$variable2"   #COMMADN将以3个空参数去执行
COMMAND "$variable2 $variable2 $variable2"   #COMMADN将以1个参数(2个空格)执行

用双引号把参数封到echo中是很有必要的,只有在单词分隔时或保留空白时可能有些问题。
Example 5.1 echo 一些诡异的变量

#!/bin/bash
#weiravars.sh:echo  诡异的变量

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

IFS='\'
echo $var   #'(] {}$"   \转换成了空格
echo "$var"   #'(]\{}$"

exit 0

IFS

是一种set变量,当shel处理"命令替换"和"参数替换"时,shell根据IFS的值,默认是space, tab, newline来拆解读入的变量,然后对特殊字符进行处理,最后重新组合赋值给该变量。

[root@localhost ~]# echo "$IFS"   #直接输出IFS看不到值
 	

[root@localhost ~]# echo "$IFS" | od -b   #转化为二进制就可以看到了
0000000 040 011 012 012
0000004
#"040"是空格,"011"是Tab,"012"是换行符"\n" 
#最后一个 012 是因为 echo 默认是会换行的

实际应用中

#!/bin/bash
OLD_IFS=$IFS #保存原始值
IFS="" #改变IFS的值
...
...
IFS=$OLD_IFS #还原IFS的原始值

5.2 转义 ()

转义是一种引用单个字符的方法。一个具有特殊含义的字符前边放上一个转义字符()就告诉shell这个字符失去了特殊的含义。
值得注意的是,在某些特定的命令和工具中,比如echo和sed,转义字符往往会起到相反的效果,它反倒有可能引发出这个字符特殊的含义。
在echo和sed中所使用的含义
\n #意味着新的一行
\r #回车
\t #tab键
\v #vertical tab(垂直tab),查看前边的Ctl-K
\b #backspace,查看前边的Ctl-H
\a #alert(如beep或flash)
\0xx #转换成8进制ASCII解码,等价于oxx

Example 5.2 转义字符

#!/bin/bash
#escaped.sh:转义字符

echo "\v\v\v\v"   #\v\v\v\v
echo -e "\v\v\v\v"   #echo -e是输出转义字符,所以会输出4个垂直tab
echo "====================="

echo -e "\042"   #"("的8进制ASCII码是42)
echo "====================="

#如果使用''($'\x')结构,就不需要-e了
echo $'\n'   #新行
echo $'\a'   #alert
echo "====================="

#8进制,结构是$'\nnn'
#[root@zhhs ~]# echo $'\t \042 \t'
#	 " 	
#16进制,结构是$'\xhhh'
#[root@zhhs ~]# echo $'\t \x22 \t'
#	 " 	

#分配ASCII字符到变量中
quote=$'\042'
echo "$quote This is a quoted string,$quote and this lies outside the quotes."
#" This is a quoted string," and this lies outside the quotes.

#变量中连续的ASCII char。
triple_underline=$'\137\137\137'   #137是'_'的八进制ASCII码。
echo "$triple_underline UNDERLINE $triple_underline"
#___ UNDERLINE ___

exit 0

另一个关于$"字符串扩展的例子见Example 34.1

\"   表达引号本身
echo "Hello"   #Hello
echo "\"Hello\",he said"   #"Hello",he said
\$   $号本身,跟在\$后的变量名,将不能扩展
echo "\$variable"   #$variable
\\   \号本身
echo "\\"   #\
#相反的
echo "\"
#这会出现第二个命令提示符,说白了就是提示你命令不全,还需要一个",如果是在脚本里,就会给出一个错误

分配给变量的字符串的元素也会被转义,但是只把一个转义字符分配给变量将会报错。

variable=\
123qwe
echo "$variable"   #123qwe。这里"\"被认为是一个续行符

variable=\    #转义一个空格
echo "$variable"   #显示空格

#variable=\\\和variable=\是一样的,都是非法定义;但是variable=\\\\是可以的
variable=\\\\
echo "$variable"   #\\

#转义一个空格,在命令行参数列表中将会阻止单词分割问题
ls -l /usr/local\ /bin/xsetroot\ /sbin/dump
#这里转义空格,会将/usr/local /bin/xsetroot /sbin/dump作为一个参数传递给ls -l

转义字符的续行功能

(cd /source/directory && tar -cf - .) | \
(cd /dest/directory && tar xpvf -)

#也可以使用如下方式:
tar cf - -C /source/directory . |
tar xpvf - -C /dest/directory

注意:如果一个脚本以|(管道)结束,那么一个(转义字符)就不用了非加不可了;但是一个好的shell脚本编写风格还是应该在行尾加上\,以增加可读性。

echo "foo
bar"
#foo
#bar

echo 'foo
bar'
#foo
#bar

echo foo\
bar
#foobar

echo "foo\
bar"
#foobar

echo 'foo\
bar'
#foo\
#bar
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值