圆括号结构
可以强制将其中的命令运行在子Shell中
cat subsvar.sh
#!/bin/bash
echo "The level of father Shell is: $BASH_SUBSHELL" #打印父Shell的层次
outervar=OUTER
( #进入子shell
echo "The level of SubShell is: $BASH_SUBSHELL"
innervar=INNER
echo "innervar=$innervar"
echo "outervar=$outervar"
)
#回到父Shell
echo "The level of father Shell is: $BASH_SUBSHELL"
if [ -z "$innervar" ] #测试子shell中定义的变量是否为空
then
echo "the \$innervar is not defined in main body."
else
echo "The \$innervar is defined in main body."
fi
执行:./subsvar.sh
The level of father Shell is: 0
The level of SubShell is: 1
innervar=INNER
outervar=OUTER
The level of father Shell is: 0
the $innervar is not defined in main body.
从上面可以看出①BASH_SUBSHELL是从0开始计的整数,它记录了shell的层次,
②子shell作用域不能在父shell里面生效
cat subsep.sh
#!/bin/bash
#在父Shell中定义变量outvar
echo "------------------IN MAINSHELL------------------"
outervar=OUTER
echo "outervar=$outervar"
( #进入子shell
echo "-----------------IN SUBSHELL--------------------"
innervar=INNER
echo "innervar=$innervar"
outervar=OUTER-INNER #更改父Shell所定义的outervar变量值
echo "outervar=$outervar"
#将innervar和outervar声明为环境变量
export innervar
export outervar
)
#回到父Shell,测试innervar和outervar的值是否与子Shell中定义的一样
echo "-----------RETURN TO MAINSHELL------------------"
echo "innnervar=$innervar"
echo "outervar=$outervar"
上面的例子说明子Shell只能继承父Shell的一些属性,但是子Shell不能反过来
改变父Shell的属性,子Shell能够从父Shell继承得的属性包括如下:
1.当前的工作目录
2.环境变量
3.标准输入、标准输出和标准错误输出
4.所有已打开的文件标识符
5.忽略的信号
6.除环境变量和.bashrc文件中定义变量之外的Shell变量
7.未被忽略的信号处理
vi subsenv.sh
#!/bin/bash
( #进入子Shell
set -C #开启-C选项,防止重定向时覆盖文件
:> outputnull #试图用冒号清空outputnull文件
)
#在父Shell覆盖一个文件,测试子Shell开启的-C选项是否对父Shell生效
cat subsenv.sh > outputnull
执行./subsenv.sh
./subsenv.sh: line 5: outputnull: cannot overwrite existing file
cat outputnull
#!/bin/bash
( #进入子Shell
set -C #开启-C选项,防止重定向时覆盖文件
:> outputnull #试图用冒号清空outputnull文件
)
#在父Shell覆盖一个文件,测试子Shell开启的-C选项是否对父Shell生效
cat subsenv.sh > outputnull
由上可以说明shell下设置-C选项对父进程不产生任何作用
vi subscol.sh
#!/bin/bash
if (set -u; : $var) #set -u, u选项是nounset的意思,表示当使用未定义变量时,输出错误信息,并强制退出
#": $var"命令的主角是冒号,此时冒号的意思是"不做任何事,只进行参数展开"
then
echo "Variable is set"
fi
Shell还可以将一个计算量较大的任务分成若干小任务并行执行,如下例子
vi subsparallel.sh
#!/bin/bash
#用圆括号结构创建三个子Shell同时执行
#每个子Shell都是搜索某个目录下与root关键字匹配的行,排序后输出到某文件
(grep -r "root" /etc/* | sort > part1) &
(grep -r "root" /usr/local/* | sort > part2) &
(grep -r "root" /lib/* | sort > part3) &
wait #等待后台执行的作业全部完成后再执行下面的命令
#将part1, part2, part3三个临时文件合并,排序后重定向到parttotal文件
cat part1 part2 part3 | sort > parttotal
echo "Run time of this script is: $SECONDS" #输出该脚本的执行时间
执行: ./subsparallel.sh
Run time of this script is: 72
wc -l parttotal
20661 parttotal