Thread: Subshell
View Single Post
  #1   (View Single Post)  
Old 12th January 2016
J65nko J65nko is offline
Join Date: May 2008
Location: Budel - the Netherlands
Posts: 3,588
Default Subshell

Just now have been playing with a subshell in OpenBSD.

Three snippets from the Command syntax section ofsh(1):
......‘;;’ is used in case statements; and lastly, ‘( .. )’ is used to create subshells.


Note: Some shells (but not this one) execute control structure commands in a subshell when one or more of their file descriptors are redirected, so any environment changes inside them may fail. To be portable, the exec statement should be used instead to redirect file descriptors before the control structure.


( list )
Execute list in a subshell. There is no implicit way to pass environment changes from a subshell back to its parent.
For this post I am only interested in the first and last snippet ....
A small test shell script:

     1  #!/bin/sh 
     3  echo setting 'a=1' ...
     4  a=1
     6  echo About to enter subshell ...
     7  (
     9  echo From within subshell the value of 'a' : $a 
    11  echo Assigning 2 to 'a' ...
    12  a=2
    14  echo From within subshell the value of 'a' : $a 
    15  cd /etc
    16  echo Working directory changed to $(pwd)
    17  echo Leaving subshell
    19  ) # end of subshell
    21  echo Back 'home' from trip to subshell ...
    22  echo Value of 'a' : $a 
    23  echo Working directory: $(pwd)
Running it:
$ ./_subshell | cat -n
     1  setting a=1 ...
     2  About to enter subshell ...
     3  From within subshell the value of a : 1
     4  Assigning 2 to a ...
     5  From within subshell the value of a : 2
     6  Working directory changed to /etc
     7  Leaving subshell
     8  Back home from trip to subshell ...
     9  Value of a : 1
    10  Working directory: /home/adriaan/Customize/PARTS
The subshell inherits the variable 'a'. The subshell assignment of '2' is lost when we exit the subshell. Same for the working directory change to /etc/.

So when I have copied /dev/MAKEDEV to /Template.mfs/dev I can start a subshell with (. Then just change dir to /Template.mfs/dev and do # ./MAKEDEV all and leave the subshell with ).

That means something like the following is not needed at all:
# --- run MAKEDEV in template directory 

echo Running $(basename $SOURCE) in $(pwd) ...
echo ./MAKEDEV all

cd ${CURDIR}
An alternative could be # sh -c 'cd /Template.mfs/dev ; ./MAKEDEV all', which is all right for simple one-liner commands. For multiple commands a subshell looks attractive.

For some feedback how this script behaves in other shells like FreeBSD's /bin/sh, or bash on *BSD or Linux, I have attached the script.
Please test and let me know
Attached Files
File Type: sh (399 Bytes, 149 views)
You don't need to be a genius to debug a pf.conf firewall ruleset, you just need the guts to run tcpdump
Reply With Quote