/ Linux Reviews / Beginners: Learn Linux / Advanced Bash-Scripting Guide - en Chapter 20. SubshellsRunning a shell script launches another instance of the command processor. Just as your commands are interpreted at the command line prompt, similarly does a script batch process a list of commands in a file. Each shell script running is, in effect, a subprocess of the parent shell, the one that gives you the prompt at the console or in an xterm window. A shell script can also launch subprocesses. These subshells let the script do parallel processing, in effect executing multiple subtasks simultaneously.
Example 20-1. Variable scope in a subshell #!/bin/bash # subshell.sh echo echo "Subshell level OUTSIDE subshell = $BASH_SUBSHELL" # Bash, version 3, adds the new $BASH_SUBSHELL variable. 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" # $inner_variable will show as uninitialized #+ because variables defined in a subshell are "local variables". # Is there any remedy for this? echo exit 0 See also Example 32-2. + Directory changes made in a subshell do not carry over to the parent shell. Example 20-2. List User Profiles #!/bin/bash
# allprofs.sh: print all user profiles
# This script written by Heiner Steven, and modified by the document author.
FILE=.bashrc # File containing user profile,
#+ was ".profile" in original script.
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 ] && less $FILE)
done
# When script terminates, there is no need to 'cd' back to original directory,
#+ because 'cd $home' takes place in a subshell.
exit 0A subshell may be used to set up a "dedicated environment" for a command group. COMMAND1 COMMAND2 COMMAND3 ( IFS=: PATH=/bin unset TERMINFO set -C shift 5 COMMAND4 COMMAND5 exit 3 # Only exits the subshell. ) # The parent shell has not been affected, and the environment is preserved. COMMAND6 COMMAND7One application of this is testing whether a variable is defined. if (set -u; : $variable) 2> /dev/null
then
echo "Variable is set."
fi # Variable has been set in current script,
#+ or is an an internal Bash variable,
#+ or is present in environment (has been exported).
# Could also be written [[ ${variable-x} != x || ${variable-y} != y ]]
# or [[ ${variable-x} != x$variable ]]
# or [[ ${variable+x} = x ]]
# or [[ ${variable-x} != x ]]
Another application is checking for a lock file:
if (set -C; : > lock_file) 2> /dev/null then : # lock_file didn't exist: no user running the script else echo "Another user is already running that script." exit 65 fi # Code snippet by Stephané Chazelas, #+ with modifications by Paulo Marcel Coelho Aragao. Processes may execute in parallel within different subshells. This permits breaking a complex task into subcomponents processed concurrently. Example 20-3. Running parallel processes in subshells (cat list1 list2 list3 | sort | uniq > list123) & (cat list4 list5 list6 | sort | uniq > list456) & # Merges and sorts both sets of lists simultaneously. # Running in background ensures parallel execution. # # Same effect as # cat list1 list2 list3 | sort | uniq > list123 & # cat list4 list5 list6 | sort | uniq > list456 & wait # Don't execute the next command until subshells finish. diff list123 list456 Redirecting I/O to a subshell uses the "|" pipe operator, as in ls -al | (command).
/ Linux Reviews / Beginners: Learn Linux / Advanced Bash-Scripting Guide |
Meet new people Adult Dating |