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
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
shell高级编程,中英文合集,均为高清版 目录如下: 第一部分. 热身 1. 为什么使用shell 编程 2. 带着一个Sha-Bang 出发(Sha-Bang 指的是#!) 2.1. 调用一个脚本 2.2. 初步的练习 第二部分. 基本 3. 特殊字符 4. 变量和参数的介绍 4.1. 变量替换 4.2. 变量赋值 4.3. Bash 变量是不分类型的 4.4. 特殊的变量类型 5. 引用(翻译的可能有问题,特指引号) 5.1. 引用变量 5.2. 转义(\) 6. 退出和退出状态 7. Tests 7.1. Test 结构 7.2. 文件测试操作 7.3. 其他比较操作 7.4. 嵌套的if/then 条件test 7.5. 检查你的test 知识 8. 操作符和相关的主题 8.1. 操作符 8.2. 数字常量 第三部分. 超越基本 9. 变量重游 9.1. 内部变量 9.2. 操作字符串 9.3. 参数替换 9.4. 指定类型的变量:declare 或者typeset 9.5. 变量的间接引用 9.6. $RANDOM: 产生随机整数 9.7. 双圆括号结构 10. 循环和分支 10.1. 循环 10.2. 嵌套循环 10.3. 循环控制 10.4. 测试与分支(case 和select 结构) 11. 内部命令与内建 11.1. 作业控制命令 12. 外部过滤器,程序和命令 12.1. 基本命令 12.2. 复杂命令 12.3. 时间/日期命令 12.4. 文本处理命令 12.5. 文件与归档命令 12.6. 通讯命令 12.7. 终端控制命令 12.8. 数学计算命令 12.9. 混杂命令 13. 系统与管理命令 13.1. 分析一个系统脚本 14. 命令替换 15. 算术扩展 16. I/O 重定向 16.1. 使用exec 16.2. 代码块的重定向 16.3. 应用 17. Here Documents 17.1. Here Strings 18. 休息时间 Part 4. 高级 19. 正则表达式 19.1. 一个简要的正则表达式介绍 19.2. 通配 20. 子shell(Subshells) 21. 受限shell(Restricted Shells) 22. 进程替换 23. 函数 23.1. 复杂函数和函数复杂性 23.2. 局部变量 23.3. 不使用局部变量的递归 24. 别名(Aliases) 25. 列表结构 26. 数组 27. /dev 和 /proc 27.1. /dev 27.2. /proc 28. 关于Zeros 和Nulls 29. 调试 30. 选项 31. Gotchas 32. 脚本编程风格 32.1. 非官方的Shell 脚本风格 33. 杂项 33.1. 交互式和非交互式的shells 和脚本 33.2. Shell 包装 33.3. 测试和比较: 另一种方法 33.4. 递归 33.5. 彩色脚本 33.6. 优化 33.7. 各种小技巧 33.8. 安全话题 33.8.1. 被感染的脚本 33.8.2. 隐藏Shell 脚本源码 33.9. 移植话题 33.10. 在Windows 下进行Shell 编程 34. Bash, 版本 2 和 3 34.1. Bash, 版本2 34.2. Bash, 版本3 35. 后记 35.1. 作者后记 35.2. 关于作者 35.3. 哪里可以取得帮助? 35.4. 制作这本书的工具 35.4.1. 硬件 35.4.2. 软件和排版软件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Achou.Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值