DaemonForums  

Go Back   DaemonForums > Miscellaneous > Programming

Programming C, bash, Python, Perl, PHP, Java, you name it.

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

Just now have been playing with a subshell in OpenBSD.

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

[snip]

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.

[snip]

( 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:

Code:
     1  #!/bin/sh 
     2  
     3  echo setting 'a=1' ...
     4  a=1
     5  
     6  echo About to enter subshell ...
     7  (
     8  
     9  echo From within subshell the value of 'a' : $a 
    10  
    11  echo Assigning 2 to 'a' ...
    12  a=2
    13  
    14  echo From within subshell the value of 'a' : $a 
    15  cd /etc
    16  echo Working directory changed to $(pwd)
    17  echo Leaving subshell
    18  
    19  ) # end of subshell
    20  
    21  echo Back 'home' from trip to subshell ...
    22  echo Value of 'a' : $a 
    23  echo Working directory: $(pwd)
Running it:
Code:
$ ./_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:
Code:
# --- run MAKEDEV in template directory 
CURDIR=$(pwd)
cd $DESTDIR

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 _subshell.sh (399 Bytes, 127 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
  #2   (View Single Post)  
Old 14th January 2016
IdOp's Avatar
IdOp IdOp is offline
Too dumb for a smartphone
 
Join Date: May 2008
Location: twisting on the daemon's fork(2)
Posts: 747
Default

Quote:
Originally Posted by J65nko
Please test and let me know
Here is one test:

Code:
% sh --version
GNU bash, version 4.2.53(2)-release (i486-slackware-linux-gnu)
...
% . subshell.sh
setting a=1 ...
About to enter subshell ...
From within subshell the value of a : 1
Assigning 2 to a ...
From within subshell the value of a : 2
Working directory changed to /etc
Leaving subshell
Back home from trip to subshell ...
Value of a : 1
Working directory: /not/etc
as expected. I'll try to post one or two more when I have a good chance.

I wanted to add two other points.

1) In this thread we discovered that sometimes subshells are used in implementing loops. So they may occur in "hidden" ways from which environment variables unexpectedly can not be passed out.

2) Once after running into that trouble, I realized a possible work-around. Instead of using an environment variable, which can't be passed out of the subshell, one could try to use the exit status of the subshell to pass information out. For example, you could bit-map (or otherwise encode) the information to be passed out into the exit status.
Code:
(
# shell does stuff here, and sets STATUS variable
exit $STATUS
)
case $? in
 0)
   ...
   ;;
  1)
   ...
  ;;
  etc...
esac
Reply With Quote
  #3   (View Single Post)  
Old 15th January 2016
IdOp's Avatar
IdOp IdOp is offline
Too dumb for a smartphone
 
Join Date: May 2008
Location: twisting on the daemon's fork(2)
Posts: 747
Default

Two more critters for your menagerie

Code:
% uname -a
NetBSD hp.lan 7.99.25 NetBSD 7.99.25 (GENERIC.201601041220Z) #0: Mon Jan  4 14:54:30 UTC 2016  builds@b41.netbs\
d.org:/home/builds/ab/HEAD/i386/201601041220Z-obj/home/source/ab/HEAD/src/sys/arch/i386/compile/GENERIC i386

% . subshell.sh
setting a=1 ...
About to enter subshell ...
From within subshell the value of a : 1
Assigning 2 to a ...
From within subshell the value of a : 2
Working directory changed to /etc
Leaving subshell
Back home from trip to subshell ...
Value of a : 1
Working directory: /not/etc

================================================

% uname -a
SunOS redacted 5.10 Generic_150400-28 sun4v sparc sun4v

% . subshell.sh
setting a=1 ...
About to enter subshell ...
From within subshell the value of a : 1
Assigning 2 to a ...
From within subshell the value of a : 2
Working directory changed to /etc
Leaving subshell
Back home from trip to subshell ...
Value of a : 1
Working directory: /not/etc
Reply With Quote
  #4   (View Single Post)  
Old 15th January 2016
J65nko J65nko is offline
Administrator
 
Join Date: May 2008
Location: Budel - the Netherlands
Posts: 3,497
Default

Thank you
__________________
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
Reply

Tags
sub-shell, subshell

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 05:18 AM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Content copyright © 2007-2010, the authors
Daemon image copyright ©1988, Marshall Kirk McKusick