提示:本篇文章接上一篇文章,主要说说()小括号和{}大括号的区别与使用。

8、()小括号

():用于一串命令执行时,()中的命令会在子Shell中运行。(和下面大括号一起说明)

9、{}大括号

{}:用于一串命令执行时,{}中的命令会在当前Shell中执行。也可以用于变量变形与替换。

(1)父Shell和子Shell

在介绍小括号和大括号的区别之前,我们先要解释一个概念,那就是父Shell和子Shell。

用户登录到Linux系统后,系统将启动一个用户Shell。在这个Shell中,可以使用Shell命令声明变量,也可以创建并运行Shell脚本程序。运行Shell脚本程序时,系统将创建一个子Shell。此时,系统中将有两个Shell,一个是登录时系统启动的Shell,另一个是系统为运行脚本程序创建的Shell。当一个脚本程序运行完毕,它的脚本Shell将终止,可以返回到执行该脚本之前的Shell。从这种意义上来 说,用户可以有许多Shell,每个Shell都是由某个Shell(称为父Shell)派生的。

在Linux系统中的默认Shell是bash,在bash中是可以调用新的bash的。在开启远程终端时候所启动的默认的交互Shell就是父Shell,只需要直接执行bash命令,就会创建一个新的Shell,这个Shell就是子Shell。

执行下面命令:

[root@localhost ~]# bash

我们就开启一个子Shell。

(2)区分父Shell子Shell

要区分是父Shell还是子Shell,需要使用前面所学的ps命令,查看进程命令来进行判断。

  • 执行ps -f查看系统进程。

  • 执行bash命令,开启一个新的Shell,并再次查看系统进程。



    可以看到上图中,第二个进程的父id是第一个进程,所以第二个进程的bash是子Shell。
  • 退出子Shell,并再次查看系统进程。



    可以看到子Shell进程结束,消失了。

(3)查看父子Shell的关系

我们可以通过pstree命令(查看进程树),来查看父子Shell的关系。

在Red Hat 6 中,所有的进程都是init进程的子进程。如下图:

我们可以看到在init进程下,开启了一个sshd的进程,这个进程就是远程登陆进程。我们执行过一次远程登陆sshd,和开启bash功能,在此bash下执行过一次pstree命令。

在当前Shell中,再执行一边bash命令,再次执行pstree命令(查看进程树)。

如下图:

我们可以从上图中看到,我在第一个bash下,又开启了一个新的bash,在新bash中执行了pstree命令。

所以说第一个bash是父(也就是父Shell),第二个bash是子(也就是子Shell)。

(4)父子Shell的关系拓展。

父Shell可以创建子Shell,在子Shell中还可以创建自己的子Shell。

它们的关系如下图所示:

下面来演示下这个关系图的Shell创建,和它们之前的关系层次。

下图中又创建了二个子Shell,总共三个子Shell。依次是子Shell, 孙Shell, 曾孙Shell。

下图使用ps -f命令,通过PPID列出谁是谁的父进程。

注意:生成子Shell的成本不低,而且速度还慢,创建嵌套的子Shell去处理命令进程性能更为严重。

通过输入exit命令能有条不絮的退出子Shell,例如上面的三个子Shell, 首先从曾孙Shell退出。

如下图所示:

注意:当没有了子Shell时,再输入exit命令,将退出控制台终端。

(5)小括号和大括号的区别

知道了父Shell和子Shell的关系,我们接着解释小括号和大括号的区别。

小括号和大括号的主要区别在于,在Shell程序执行的时候,小括号或者大括号中的内容是在父Shell执行还是在子Shell中执行。

下面我们总结一下小括号和大括号的主要区别:

  • ()中执行一串命令时,需要重新开一个子Shell进行执行。

    在当前Shell中name=ss,当执行到()中命令的时候,会自动开启一个子Shell,在子Shell中name的变量赋予了mm,当()中命令运行完,子Shell进程就结束了,进程消失。里边的变量都不会保存,并自动返回到父Shell中,也就是回归到当前Shell,name的值还是原来Shell中赋予的ss值。

    示例如下:
    #在父Shell中定义变量name的值是ss
    [root@localhost ~]# name=ss #如果用()括起来一串命令,这些命令都可以执行。
    #给name变量重新赋值,但是这个值只在子Shell中生效
    [root@localhost ~]#(name=mm;echo $name)
    mm #父Shell中name的值还是ss,而不是mm
    [root@localhost ~]# echo $name
    ss
  • { }中执行一串命令时,是在当前Shell执行。
    #用大括号来进行串命令的执行时
    #name变量的修改是直接在父Shell当中的
    #注意大括号的格式
    [root@localhost ~]# { name=mm;echo $name; }
    mm #所以name变量的值已经被修改了
    [root@localhost ~]# echo $name
    mm

    就相当于直接在当前Shell执行{}中的语句,那么不写{}的结果是一样的。

  • (){}都是把一串的命令放在括号里面,并且命令之间用号隔开。
  • ()最后一个命令可以不用分号结尾。
    [root@localhost ~]# ( name=lm; echo $name )
  • {}中最后一个命令要用分号结尾。
    [root@localhost ~]# { 空格 name=lm; echo $name; }
  • {}中的第一个命令和左括号之间必须要有一个空格。
    [root@localhost ~]# { 空格 name=lm; echo $name; }
  • ()里的各命令不必和括号有空格。
  • (){}中,括号里面的某个命令的重定向只影响该命令,但括号外的重定向则影响到括号里的所有命令。

说明:小括号和大括号不太好理解,用的也不是太多,能看懂即可,工作中用不用在你自己。

10、[]中括号

[]:用于变量的测试。(之后详解讲解)

『忘了再学』Shell基础 — 10、Bash中的特殊符号(二)的更多相关文章

  1. 『忘了再学』Shell基础 — 24、Shell正则表达式的使用

    目录 1.正则表达式说明 2.基础正则表达式 3.练习 (1)准备工作 (2)*练习 (3).练习 (4)^和$练习 (5)[]练习 (6)[^]练习 (7)\{n\}练习 (8)\{n,\}练习 ( ...

  2. 『忘了再学』Shell基础 — 9、Bash中的特殊符号(一)

    目录 1.双单引号 2.双引号 3.$符号 4.反引号 5.$()符号 6.#符号 7.\符号 1.双单引号 '':单引号.在单引号中所有的特殊符号,如$和"`"(反引号)都没有特 ...

  3. 『忘了再学』Shell基础 — 11、变量定义的规则和分类

    目录 1.定义变量的规则 2.变量的分类 1.定义变量的规则 在定义变量时,有一些规则需要遵守 变量名称可以由字母.数字和下划线组成,但是不能以数字开头.如果变量名是2name则是错误的. 在Bash ...

  4. 『忘了再学』Shell基础 — 16、位置参数变量

    目录 1.位置参数变量$n 2.位置参数变量$*和$@ 3.位置参数变量$# 位置參数变量的作用主要用于脚本的传参. 位置參数变量的名称和作用都是确定不能改变的,但是该变量的内容是可以更改的,也就是变 ...

  5. 『忘了再学』Shell基础 — 2、Shell的作用与分类

    目录 1.Shell的作用 2.Shell的分类 1.Shell的作用 Shell除了能解释用户输入的命令,将它传递给内核,还可以: 调用其他程序,给其他程序传递数据或参数,并获取程序的处理结果. 在 ...

  6. 『忘了再学』Shell基础 — 14、环境变量(二)

    目录 1.PS1变量的作用 2.PS1变量的查看 2.PS1可以支持的选项 3.PS1环境变量的配置 4.总结 提示: 在Linux系统中,环境变量分为两种.一种是用户自定义的环境变量,另一种是系统自 ...

  7. 『忘了再学』Shell基础 — 3、echo命令的介绍与使用

    目录 1.echo命令的作用 2.echo命令的基本用法 3.echo命令的-e选项用法 4.echo命令一些特殊用法 (1)输出字符带有字体颜色 (2)输出字符带有背景颜色 在讲Shell脚本之前, ...

  8. 『忘了再学』Shell基础 — 25、扩展正则表达式

    目录 1.扩展正则表达式说明 2.练习 (1)+和?练习 (2)|和()练习 3.注意(重点) 1.扩展正则表达式说明 熟悉正则表达式的童鞋应该很疑惑,在其他的语言中是没有扩展正则表达式说法的,在Sh ...

  9. 『忘了再学』Shell基础 — 30、sed命令的使用

    目录 1.sed命令说明 2.行数据操作 (1)查看文件中的数据 (2)删除文件中的数据 (3)向文件中追加数据 (4)向文件中插入数据 (5)修改文件中的多行数据(删除,追加,插入) (6)替换文件 ...

随机推荐

  1. Python 基础知识自检,离深入掌握 Python 还有多远

    1. 模块化编程思想 模块化编程是 Python 的基本思想.初学 Python,都应该使用过小海龟.随机.数学模块.使用模块之前,需要导入模块,然后根据自己的问题需要使用这些模块. Python 提 ...

  2. CentOS 7 源码安装 Zabbix 6.0

    Zabbix 主要有以下几个组件组成: Zabbix Server:Zabbix 服务端,是 Zabbix 的核心组件.它负责接收监控数据并触发告警,还负责将监控数据持久化到数据库中. Zabbix ...

  3. 老徐和阿珍的故事:Runnable和Callable有什么不同?

    人物背景: 老徐,男,本名徐福贵,从事Java相关研发工作多年,职场老油条,摸鱼小能手,虽然岁数不大但长的比较着急,人称老徐.据说之前炒某币败光了所有家产,甚至现在还有欠债. 阿珍,女,本名陈家珍,刚 ...

  4. 8元电调调参教程(使用Arduino Uno)| BLHeli无刷电调的固件烧写及调参

    前言 淘某上有款8元电调,性价比很高,但是需要简单设置一下 1.材料清单 (1)Arduino UNO开发板 (2)BLHeliSuite 16.7.14.9.0.1 调参软件及固件已上传Gitee: ...

  5. C#中的类型转换-自定义隐式转换和显式转换

    目录 前言 基础知识 示例代码 实际应用 问题 答案 报错 用户定义的转换必须是转换成封闭类型,或者从封闭类型转换 参考 其他 应用和设计 读音 参考 前言 有时我们会遇到这么一种情况:在json数据 ...

  6. ThreadPoolTaskExecutor原理、详解及案例

    为什么要用线程池? 服务器应用程序中经常出现的情况是:单个任务处理的时间很短而请求的数目却是巨大的. 构建服务器应用程序的一个过于简单的模型应该是:每当一个请求到达就创建一个新线程,然后在新线程中为请 ...

  7. 谷歌浏览器postman插件安装,亲测可用

    将谷歌浏览器进入扩展程序,将crx文件拖入即可. https://pan.baidu.com/s/1rIEe9RSby5EgTkygSx_dDA 百度云链接: https://pan.baidu.co ...

  8. 汽车最强大脑ECU和单片机是什么关系

    先上图一张,据说这是某个F1赛车的动力总成ECU. 定睛一看,这不就是两个英飞凌的单片机的合体嘛. ECU的定义 ECU原来指的是engine control unit,即发动机控制单元,特指电喷发动 ...

  9. 顺利通过EMC实验(10)

  10. 如何更愉快地使用rem —— 别说你懂CSS相对单位

    前段时间试译了Keith J.Grant的CSS好书<CSS in Depth>,其中的第二章<Working with relative units>,书中对relative ...