Shell 中的命令替换及参数扩展 | Linux 中国

2017 年 12 月 23 日 Linux中国 作者:季文康
今天和大家分享的主要是 “命令替换” 以及 “参数扩展” 。
-- 季文康

本文导航
转载自 | http://www.cnblogs.com/itxdm/p/something_of_shellscirpt.html
 作者 | 季文康

前言

其实,你现在阅读到的是第三版的文章(几乎全部重构)。记得我写第一版的时候,还是一名 “参赛选手”。后来比赛失利便和朋友一起做 IDC 创业。第二次改的时候,是我发现阅读量在俩三个月内直接自己站点 top 到第一,加上参与了开源社区,维护了 LCTT-CLI 项目。最后第三次也就是这次,是因为通过了 RHCE 模拟考加上一年多积累。所以这次的内容或是排版都应是最棒!BTW:这篇文章在我的博客IT兄弟盟[2],依旧是第一的阅读量!

一开始写这篇文章是因为兼职创业 IDC 公司运维,需要一点 shell script 来实现某些需求。虽然现在已经是 Python 的时代了。插个话题,我怎么理解 Python 和 Shell 呢?拿游泳来做个比喻:前者是正规游泳馆,有正规教练辅助相伴;后者是乡下小湖泊,麻雀虽小五脏俱全。人工智能选中的 Python 势必锋不可当,经典的 Shell 也相当精妙绝伦。比如以前我写 Shell 的时候用了很多 if else 语句、 case 语句,有 test 语句,懂得 || && ; 辅助,这是最小白的。后面学习了很多比较运算符,但多数还是在积累命令数量以及条件语句。再到现在,我开始去思考命令和命令之间存在的关系、语句分隔符的意义、BASH 控制结构等等。

所以今天和大家分享的主要是 “命令替换” 以及 “参数扩展” 。

什么是命令替换

简单的来说就是在 SHELL 内嵌套多条命令,一次性执行得到结果。

1、一层 SHELL 嵌套

   
     
     
     
  1. # echo `whoami`

  2. # echo $(whoami)

  3. # echo "hello,`whoami`"

  4. # echo "hello,$(whoami)"

2、二层 SHELL 嵌套

   
     
     
     
  1. # echo `cat ./gn2.txt` | sed -s "s;$; --list;"

使用 ``读取文件内容,再使用管道符二次处理后。执行!

注意:这里已经用了一层嵌套,以下多个小节会套用以实现二层嵌套。

a. 使用 "$()" 进行二层嵌套

b. 使用 "|" 进行命令导向

c. 注意事项以及解答一些疑问

可能有读者已经注意到了,之前在简单 SHELL 一层嵌套中说了嵌套还有另一种。那为什么不使用 ` ` 进行嵌套。

◈ 根本的原因是: ` ` 不支持命令嵌套执行!
◈ 强制执行。也只能认出第一组,其余按照空格作为间隔各个执行 或 按照管道符(含)直到末尾执行。
◈ 比较陈旧。容易与“单引号”混淆。
◈ 它是美式键盘左上角 ESC 下面的包含  ~ 的反引号键!
◈ 已有替代品。 $(...) 格式受到POSIX标准支持,也利于嵌套。
◈  $() 可以多层嵌套类似  $($($())) ,但如果内部有一个 ` ` 也是可以执行的哟(出于兼容考虑)!

3、进阶

之前我们介绍了 `` 和 $(...) ,这俩种命令执行。

想来现在你一定对命令执行有比较深的理解了。现在,我们需要再进阶一下~

1、 (cmd) 与 {var}

关于 ( ) 与 { },和 命令替换 一样都是 shell 扩展 父类下的相关概念。

提示:{} 头部大括号右侧必须有一个空格,尾部括号左侧必须有分号结尾。

   
     
     
     
  1. # ( echo firest;echo second; )

  2. # { echo third;echo fourth; }

注意: ( ) 只是对一串命令重新开一个 子 shell 进行执行, { } 对一串命令在 当前 shell 执行。

2、() 与 {} 造成的影响

a. () 括号内的语句影响在括号内

   
     
     
     
  1. # var=source

  2. # ( echo $var;var=global;echo $var; )

  3. # echo $var

b. {} 括号内的语句影响到全局。

   
     
     
     
  1. # echo $var

  2. # { echo $var;var=global;echo $var; }

  3. # echo $var

注意:{} 改变 var 的变量以后,外部也受到了影响。

什么是参数扩展

参数扩展的基本格式是 ${ parameter },扩展的结果是 ${ parameter }被替换为相应的值。

1、实例一

   
     
     
     
  1. echo $1 $11

  2. echo $1 ${11}

首先解释下 ${1..9} 是什么意思。在我们写 Shell 时必不可免的需要传递参数以实现自定义变量。当超过阿拉伯数字 9 以后。就需要使用 ${ parameter } 明确告诉Shell第 11 个参数是 ${11}

提示:上图显示 101 就是因为 $11 不满足 [1-9]{1} 。系统将 11 拆分成 $1 和 1 ,所以运算后结果是 101

2、实例二

   
     
     
     
  1. ban=ban

  2. echo a $banana

  3. echo a ${ban}ana

这个实例中,我想输出 banana 。已经定义了一个 ban 的变量为 ban ,只要加上 ana 就可以成为 “笨啦啦”。

但是很显然的不加 {} 是无法做到使变量 $ban 配合 ana 显示出 banana 的!

什么是变量扩展

从官方定义上来说,我并不应该将 “变量扩展” 无中生有出来。

$ 字符引入参数扩展,命令替换或算术扩展。" —— 官方手册

主要是出于俩个方面考虑:

◈ 多数接受。国内出现了大量 ”变量扩展“ 的文章,多数人已经接受这个名称。
◈ 便于理解。参数就是  ${...} 括号内的东西,而变量一词可表示所有操作围绕变量展开。
◈ 便于记录。切分以后,对写这篇文章的排版有帮助。亦可以从基础、中级、高级有一定水平划分。

实例:

   
     
     
     
  1. var='This is one test sentence.'

  2. var1=parameter

  3. var2=word

现在我们有了这样的一个句子,我希望做一些判断、摘取(或者说:切片)或修改。我该如何操作?

1、变量替换

a. ${parameter:-word}

   
     
     
     
  1. # echo ${var1:-$var2}

  2. parameter

  3. # var1=

  4. # echo ${var1:-$var2}

  5. word

如果 var1 未设置或为空,则替换成 var2

b. ${parameter:=word}

同上。位置参数和特殊参数不能以这种方式分配。

c. ${parameter:?word}

   
     
     
     
  1. # var1=

  2. # echo ${var1:?var2}

  3. bash: var1: var2

  4. # echo $?

  5. 1

当变量 var1 未设置或为空,shell 也是可交互时,进行报错并且退出。如果 shell 不可交互,则发生变量替换。

d. ${parameter:+word}

   
     
     
     
  1. # echo $var1

  2. parameter

  3. # echo $var2

  4. word

  5. # echo ${var1:+$var2}

  6. word

  7. # echo $var1

  8. parameter

如果 var1 为空或未设置,那么就什么都不做。不然使用 var2 进行替换。

提示: 在我测试的时候,我发现并不是全局生效的。

2、变量切片

a. 范围切片(同方向)

   
     
     
     
  1. # echo ${var:8:17}

  2. one test sentence

注意:俩个数字都是从头开始数的。

b. 范围切片(非同向)

   
     
     
     
  1. # echo ${var:8:-1}

  2. one test sentence

  3. # echo ${var:8:(-1)}

  4. one test sentence

提示:俩种写法都是正确的。

c. 切片位置

   
     
     
     
  1. # a='This is one'

  2. # echo ${#a}

  3. 11

提示 :首先建立变量 a='This is one' ,然后使用 echo ${#a} 将字符数量读了出来。

3、变量修改

a. 简单修改

   
     
     
     
  1. # echo ${var}

  2. This is one test sentence.

  3. # echo ${var/one/a}

  4. This is a test sentence.

提示:个人认为这种是最好的方式了,可以范围式修改(包含删除)。

b. 简单删除

   
     
     
     
  1. # echo ${var%sentence.}

  2. This is one test

   
     
     
     
  1. # echo ${var#This is}

  2. one test sentence.

c. 附:表格

< 如显示不全,请左右滑动 >
变量设置方式 说明
${变量#关键字} 若变量内容从开始的数据符合“关键字”,则将符合的最数据删除
${变量##关键字} 若变量内容从开始的数据符合“关键字”,则将符合的最数据删除
${变量%关键字} 若变量内容从开始的数据符合“关键字”,则将符合的最数据删除
${变量%%关键字} 若变量内容从开始的数据符合“关键字”,则将符合的最数据删除
${变量/旧字符串/新字符串} 若变量内容符合“旧字符串”,则首个旧字符会被新字符替换
${变量/旧字符串//新字符串} 若变量内容符合“旧字符串”,则全部旧字符会被新字符替换

更深入学习,探索资料

◈  Bash 实例,第二部分 [3]
◈ Bash 参考手册: Bash Reference Manual [4]
◈ Shell-Expansions 章节: Shell-Expansions [5]
◈ Shell Parameter Expansion 章节  Shell Parameter Expansion [6]

推荐文章

< 左右滑动查看相关文章 >

点击图片、输入文章 ID 或识别二维码直达


登录查看更多
0

相关内容

【2020新书】使用高级C# 提升你的编程技能,412页pdf
专知会员服务
57+阅读 · 2020年6月26日
【实用书】Python技术手册,第三版767页pdf
专知会员服务
234+阅读 · 2020年5月21日
【高能所】如何做好⼀份学术报告& 简单介绍LaTeX 的使用
【实用书】Python爬虫Web抓取数据,第二版,306页pdf
专知会员服务
117+阅读 · 2020年5月10日
深度神经网络实时物联网图像处理,241页pdf
专知会员服务
76+阅读 · 2020年3月15日
【书籍推荐】简洁的Python编程(Clean Python),附274页pdf
专知会员服务
179+阅读 · 2020年1月1日
【电子书】C++ Primer Plus 第6版,附PDF
专知会员服务
87+阅读 · 2019年11月25日
msf实现linux shell反弹
黑白之道
49+阅读 · 2019年8月16日
已删除
AI掘金志
7+阅读 · 2019年7月8日
Python用于NLP :处理文本和PDF文件
Python程序员
4+阅读 · 2019年3月27日
I2P - 适用于黑客的Android应用程序
黑白之道
30+阅读 · 2019年3月6日
34个最优秀好用的Python开源框架
专知
9+阅读 · 2019年3月1日
快乐的迁移到 Python3
Python程序员
5+阅读 · 2018年3月25日
Arxiv
7+阅读 · 2018年1月30日
VIP会员
相关VIP内容
【2020新书】使用高级C# 提升你的编程技能,412页pdf
专知会员服务
57+阅读 · 2020年6月26日
【实用书】Python技术手册,第三版767页pdf
专知会员服务
234+阅读 · 2020年5月21日
【高能所】如何做好⼀份学术报告& 简单介绍LaTeX 的使用
【实用书】Python爬虫Web抓取数据,第二版,306页pdf
专知会员服务
117+阅读 · 2020年5月10日
深度神经网络实时物联网图像处理,241页pdf
专知会员服务
76+阅读 · 2020年3月15日
【书籍推荐】简洁的Python编程(Clean Python),附274页pdf
专知会员服务
179+阅读 · 2020年1月1日
【电子书】C++ Primer Plus 第6版,附PDF
专知会员服务
87+阅读 · 2019年11月25日
相关资讯
msf实现linux shell反弹
黑白之道
49+阅读 · 2019年8月16日
已删除
AI掘金志
7+阅读 · 2019年7月8日
Python用于NLP :处理文本和PDF文件
Python程序员
4+阅读 · 2019年3月27日
I2P - 适用于黑客的Android应用程序
黑白之道
30+阅读 · 2019年3月6日
34个最优秀好用的Python开源框架
专知
9+阅读 · 2019年3月1日
快乐的迁移到 Python3
Python程序员
5+阅读 · 2018年3月25日
Top
微信扫码咨询专知VIP会员