『忘了再学』Shell基础 — 10、Bash中的特殊符号(二)
提示:本篇文章接上一篇文章,主要说说
()
小括号和{}
大括号的区别与使用。
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、[]
中括号
[]
:用于变量的测试。(之后详解讲解)
最新文章
- PHP注册审核做法
- cvKMeans2函数用法概述
- C#删除字符串最后一个字符的几种方法
- JS面向对象组件(一) ---包装对象与原型链
- SCVMM之Windows Server2012 R2新功能
- 节点属性(DOM对象)
- 用微信点单 订餐系统打造属于个人的O2O外卖订餐行业商业平台
- 第1章 初识java----Java简介
- JAVA基础面试(五)
- HTML,CSS---问题记录
- 基于struts2、hibernate、spring、shiro、MySQL的项目开发
- py2neo的使用(转)
- linux下查看动态链接库so文件的依赖的相关组建
- tomcat中web项目编译后的结构
- kbengine学习1 安装
- python中序列化json模块和pickle模块
- iPhone 物理尺寸与分辨率
- 机器学习之路:python 文本特征提取 CountVectorizer, TfidfVectorizer
- ArcGIS高程Z值的去除方法
- C++中的字节对齐分析
热门文章
- 活用Windows Server 2008系统的几种安全功能
- SpringBoot 如何实现异步编程,老鸟们都这么玩的!
- MySQL&;SQL server&;Oracle&;Access&;PostgreSQL数据库sql注入详解
- minouche
- STM32注意事项
- 基于MRS-ClickHouse构建用户画像系统方案介绍
- TypeScript编译tsconfig.json配置
- SpringCloud项目中接入Nacos作为注册中心
- mac下启动/停止/重启mysql服务
- 在虚拟机里面运行java程序