Sub-Processing ============== Sub-Shells ---------- A Subshell is an execution context similar to a sub-process, but is more optimized and lightweight Than ``fork`` and ``exec`` system calls. .. caution:: The sub-shell functions behave almost-identically to sub-processing, except that parent local variables do NOT need to be exported to be visible to a sub-shell .. code-block:: bash cd /tmp # creating a file with 4 variable assignments echo 'a=apples' > fruits.env echo 'b=berries' >> fruits.env echo 'c=carrots' >> fruits.env echo 'd=durian' >> fruits.env z=zebra ( set -a source fruits.env set +a bash -c 'printf "$a $b $c $d \n"' # z doesn't need to be exported to be visible to the sub-shell echo $z # exporting z to make it available to a sub-process export z bash -c 'printf "$z\n"' ) [[ $a || $b || $c || $d ]] || printf "variables not visible in the parent shell\n" Bash Functions -------------- There are two types of functions * Function executed in the current shell in the form of ``function func_name(){command-list}`` * Function executed in a sub-shell ``function func_name()(command-list)`` A function can be exported (exporting functions) with ``export -f func_name`` Here are two examples to illustrate the differences between the two types of functions .. code-block:: bash # not exported a=apples # shell PID echo $BASHPID function play(){ # same shell PID echo $BASHPID # local variables to the caller are visible echo "a is $a" b=berries } # execute the function play # local variables set within the function are visible to the caller echo "b is $b" The other type is executed in a sub-shell .. code-block:: bash function play()( # different PID echo $BASHPID # parent-local variable is visible to the child echo "a = $a" # parent-exported variable is visible to the child echo "z is $z" # only available to the child and its children export b=berries # can provide return status return 0 ) # not exported a=apples export z=zebra # shell PID echo $BASHPID # this function call sees the two variables a=apples and z=zebra play [[ $? ]] && echo "last command status successful" # child env variables cannot be seen by the parent process [[ $b ]] || echo "variable b can never be visible to the parent" # this call sees a different variable for a a=apricot play # but its value remains the same in the parent echo $a Passing Arguments ----------------- There are two mechanisms for passing arguments to a sub-process * positional arguments * Environment Variables command line arguments involve the following special variables * ``$#`` the count of positional args starting of a function from 1 * ``$0`` zeroth positional param is the command with which the child process was executed * ``$1`` first positional parameter passed as a command line argument, if it exists * ``$*`` and ``$@`` expansion of positional arguments, starting from 1 * ``"$*"`` is equivalent to ``"$1 $2 ..."`` * ``"$@"`` is equivalent to ``"$1" "$2" ...`` .. code-block:: bash function printer()( echo "count of passed arguments is: $#" [[ $1 ]] && echo "the first argument is $1" [[ $2 ]] && echo "the second argument is $2" echo "all arguments are $@" ) printer apples bananas printer tigers