高级shell编程笔记(第二十章 子shell)

第二十章 子shell

每个 shell 脚本有效地运行在父 shell 的一个子进程里。这个父 shell 是指在一个控制终端或在一个 xterm 窗口中给你命令指示符的进程。

shell 脚本也能启动他自已的子进程。这些子 shell(即子进程)使脚本因为效率而同时进行多个子任务执行时能做串行处理。

一般来说,脚本里的一个外部命令(external command)能生成(forks)出一个子进程,然而 Bash 内建(builtin)的命令却不这样做,因此,内建命令比起外部的等价命令执行起来更快。

圆括号里的命令列表

(命令 1;命令 2;命令 3;...)

嵌在圆括号里的一列命令在一个子 shell 里运行。

注意: 在子 shell 里的变量不能被这段子 shell 代码块之外的脚本访问。这些变量是不能被产生这个子 shell 的父进程存取的,实际上它们是局部变量 。

Example 20-1 子shell中的变量作用域

#!/bin/bash
#
echo
echo "Subshell level OUTSIDE subshell = $BASH_SUBSHELL"
echo
outer_variable=Outer
(
    echo "Subshell level INSIDE subshell = $BASH_SUBSHELL"
    inner_variable=Inner
    
    echo "From subshell, \"inner_variable\" = $inner_variable"
    echo "From subshell, \"outer\" = $outer_variable"
)
echo
echo "Subshell level OUTSIDE subshell = $BASH_SUBSHELL"
echo

if [ -z "$inner_variable" ];then
  echo "inner_variable undefined in main body of shell"
else
   echo "inner_variable defined in main body of shell"
fi

echo "From main body of shell, \"inner_variable\" = $inner_variable"
echo
exit 0

参考例子31-2

在子shell中的目录更改不会影响到父shell

Example 20-2 列出用户的配置文件

#!/bin/bash
#
FILE=.bashrc

for home in `awk -F: '{print $6}' /etc/passwd`
do
  [ -d "$home" ] || continue   # 如果没有家目录,跳过此次循环.
  [ -r "$home" ] || continue   # 如果目录没有读权限,跳过此次循环.
  (cd $home; [ -e $FILE] && less $FILE)
done

exit 0

子shell可用于为一组命令设定临时的环境变量

COMMAND1
COMMAND2
COMMAND3
(
IFS=: 
PATH=/bin
unset TERMINFO
set -C
shift 5
COMMAND4
COMMAND5
exit 3   # 只是从子 shell 退出。
 )
# 父 shell 不受影响,变量值没有更改。
COMMAND6
COMMAND7

它的一个应用是测试是否一个变量被定义了

if (set -u; : variable) 2>/dev/null
#set -u:遇到不存在的变量就会报错
then
  echo "Variable is set"
fi
#变量已经在当前脚本中被设置,或是 Bash 的一个内部变量,或是可见环境变量(指已经被导出的环境变量).

另一个应用是检查一个加锁的文件

if (set -C; : > lock_file) 2>/dev/null
#set -C:所产生的文件无法覆盖已存在的文件
then
  :
else
  echo "Another user is already running that script."
exit 65
fi  

进程在不同的子 shell 中可以串行地执行。这样就允许把一个复杂的任务分成几个小的子问题来同时地处理。

Example 20-3 在子shell里进行串行处理

(cat list1 list2 list3 | sort | uniq > list123) &
(cat list4 list5 list6 | sort | uniq > list456) &
#列表的合并和排序同时进.
#放到后台运行可以确保能够串行执行.

##和下面的有相同的作用:
#cat list1 list2 list3 | sort | uniq > list123 &
#cat list4 list5 list6 | sort | uniq > list456 &
wait   ##在所有的子 shell 执行完成前不再执行后面的命令.
diff list123 list456

用"|"管道操作把 I/O 流重定向到子 shell。例如 ls -al | (command)。

注意: 在一个花括号内的代码块不会运行一个子 shell。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值