Bash脚本编程之subshell

5次阅读

共计 1807 个字符,预计需要花费 5 分钟才能阅读完成。

(command1;command2;command3;…) 会启动子 shell。子 shell 可以访问父 shell 的变量,对父 shell 变量的改动只在子 shell 中有效;子 shell 中定义的变量是局部变量,外部不能访问:
#!/bin/bash
# subshell.sh

echo “We are outside the subshell.”
echo “Subshell level OUTSIDE subshell = $BASH_SUBSHELL”
echo; echo

outer_variable=Outer
global_variable=

(
echo “We are inside the subshell.”
echo “Subshell level INSIDE subshell = $BASH_SUBSHELL”

inner_variable=Inner
global_variable=”$inner_variable”

echo “From inside subshell, \”inner_variable\” = $inner_variable”
echo “From inside subshell, \”outer\” = $outer_variable”
)

echo; echo
echo “We are outside the subshell.”
echo “Subshell level OUTSIDE subshell = $BASH_SUBSHELL”
echo “From main body of shell, \”inner_variable\” = $inner_variable”
# $inner_variable will show as blank (uninitialized)
#+ because variables defined in a subshell are “local variables”.
echo “global_variable = “$global_variable””

echo

# =======================================================================

# Additionally …

echo “—————–“; echo

var=41 # Global variable.

(let “var+=1”; echo “\$var INSIDE subshell = $var”) # 42

echo “\$var OUTSIDE subshell = $var” # 41
# Variable operations inside a subshell, even to a GLOBAL variable
#+ do not affect the value of the variable outside the subshell!

exit 0
在子 shell 中对目录的改变不会影响父 shell:
#!/bin/bash
# allprofs.sh: Print all user profiles.

FILE=.bashrc # File containing user profile.

for home in `awk -F: ‘{print $6}’ /etc/passwd`
do
[-d “$home”] || continue # If no home directory, go to next.
[-r “$home”] || continue # If not readable, go to next.
(cd $home; [ -e $FILE] && cat $FILE)
done

# When script terminates, there is no need to ‘cd’ back to original directory,
#+ because ‘cd $home’ takes place in a subshell.

exit 0
程序可以在不同的子 shell 中并行执行:
#!/bin/bash
# subshell.sh

# 在后台运行以确保并行执行
(ping -c 10 127.0.0.1 > /dev/null) &
(ping -c 20 127.0.0.1 > /dev/null) &

# 等同于:
# ping -c 10 127.0.0.1 > /dev/null &
# ping -c 20 127.0.0.1 > /dev/null &

# 通过 ps 可以发现两条子命令都是当前脚本启动的子 shell,拥有不同的进程 ID

# 直到子 shell 执行完成才执行后续命令
wait

echo “finished”
I/ O 重定向到子 shell 使用管道操作符,例如 ls -al | (command)

正文完
 0