old-www/LDP/LG/issue95/tag/1.html

194 lines
7.2 KiB
HTML

<!--startcut ==============================================-->
<!-- *** BEGIN HTML header *** -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML><HEAD>
<META NAME="generator" CONTENT="lgazmail v1.4G.k">
<TITLE>The Answer Gang 95: Efficiency regards running script in a subshell () and a seperate shell</TITLE>
</HEAD><BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#0000AF"
ALINK="#FF0000">
<!-- *** END HTML header *** -->
<!--endcut ==============================================-->
<!-- begin 1 -->
<H3 align="left"><img src="../../gx/dennis/qbubble.gif"
height="50" width="60" alt="(?) " border="0"
>Efficiency regards running script in a subshell () and a seperate shell</H3>
<p><strong>From Nimish kamerkar
</strong></p>
<p></strong></p>
<p align="right"><strong>Answered By: Thomas Adam
</strong></p>
<P><STRONG>
Hi Answer Gang,
</STRONG></P>
<P><STRONG>
Which method is more efficient;
Running a command in () or running it in a seperate shell?
Can the answer include differences in how the processes
are spawned? (i.e. fork exec etc)
</STRONG></P>
<blockQuote>
<IMG SRC="../../gx/dennis/bbub.gif" ALT="(!)"
HEIGHT="28" WIDTH="50" BORDER="0"
> [Thomas]
OK. This is usually application/situation dependant. If you have something
like:
</blockQuote>
<blockquote><pre>#!/bin/bash
echo $(whereis xterm)
</pre></blockquote>
<blockQuote>
What you are doing there is forcing the command "whereis xterm" to run in
a subshell (denoted between ()'s). A "subshell" is just another instance
of the command-line interpreter, running your program. Thus, a "subshell"
in this instance means that the main shell script is its parent, i.e.
assume that we called the script above "parent.sh" then when the subshell
executed you'd get:
</blockQuote>
<blockquote><pre>|-parent.sh
|-----subshell
</pre></blockquote>
<blockQuote>
This is also known as forking -- i.e. where the process breaks off from
the main caller, to form another.
</blockQuote>
<blockQuote>
<TT>"exec()</TT>"'ing a process however, means that the currently running process
is replaced by the program that is to be exec'ed. Thus unlike above
where-by the subshell ran under a new instance, the following script
exec's itself:
</blockQuote>
<p align="center">See attached <tt><a href="../misc/tag/exec-anything.bash.txt">exec-anything.bash.txt</a></tt></p>
<blockQuote>
What this is doing is it will echo the first two lines, sleep for a second
and then re-spawn itself. What you'll see is the same message above. The
echo line will NEVER show, because it is after the program ($0 denotes the
program's name) that is being (re)exec'ed.
</blockQuote>
<P><STRONG>
<IMG SRC="../../gx/dennis/qbub.gif" ALT="(?)"
HEIGHT="28" WIDTH="50" BORDER="0"
>
My question is how are invoking a program in a <TT> subshell()</TT> and
invoking it in a seperate shell different, as regards fork &amp; exec. I am asking
this as the environment inherited by both is different. I started thinking
of this really because I remembered reading somewhere sometime that invoking
it in () is more efficient than in a seperate shell. But as far as I can see,
both processes should need fork and exec.
</STRONG></P>
<P><STRONG>
Only difference is in (), both the
local and global environment variables are initialised, and in a seperate shell,
only global environment variables are initialised. By that logic actually, the
seperate process should be more efficient than the one in ()!
</STRONG></P>
<blockQuote>
<IMG SRC="../../gx/dennis/bbub.gif" ALT="(!)"
HEIGHT="28" WIDTH="50" BORDER="0"
> [Thomas]
Those variables that are exported are "global" anyway, so you don't need
to describe them in this way.
</blockQuote>
<blockQuote>
It depends. A subshell can be efficient if you want to ensure that a task
running under another shell script is carried out to completion before the
next one is executed (a good example of this would be tarring files over
ssh on a pipe).
</blockQuote>
<blockQuote>
Of course, invoking a subshell program means that if the parent dies or is
kill -9'ed, whatever, then the child process is also killed along with it.
That is something you might want to consider.
</blockQuote>
<blockQuote>
Normally, when you write a shell script, and you want to end the script
by calling another one then you would "exec" the program name, since
there is no need for the shell process to <TT> fork()</TT>.
</blockQuote>
<blockQuote>
If you need two independant processes to communicate concurrently then
using a <TT> fork()</TT> would be best.
</blockQuote>
<P><STRONG>
<IMG SRC="../../gx/dennis/qbub.gif" ALT="(?)"
HEIGHT="28" WIDTH="50" BORDER="0"
>
Hello Thomas/Answer Gang,
</STRONG></P>
<P><STRONG>
Thanks for the patient unravelling of the intricacies!
</STRONG></P>
<P><STRONG>
With Warm Regards
-Nimish.
</STRONG></P>
<!-- end 1 -->
<!-- *** BEGIN copyright *** -->
<hr>
<CENTER><SMALL><STRONG>
<h5>
<br>Copyright &copy; 2003
<br>Copying license <A HREF="">http://www.linuxgazette.com/copying.html</A>
<BR>Published in Issue 95 of <i>Linux Gazette</i>, October 2003</H5>
</STRONG></SMALL></CENTER>
<!-- *** END copyright *** -->
<SMALL><CENTER><H6 ALIGN="center">HTML script maintained by
<A HREF="mailto:star@starshine.org">Heather Stern</a> of
Starshine Technical Services,
<A HREF="http://www.starshine.org/">http://www.starshine.org/</A>
</H6></SMALL></CENTER>
<HR>
<!--startcut ======================================================= -->
<P> <hr>
<!-- begin tagnav ::::::::::::::::::::::::::::::::::::::::::::::::::-->
<p align="center">
<table width="100%" border="0"><tr>
<td align="right" valign="center"
><IMG ALT="" SRC="../../gx/navbar/left.jpg"
WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="middle" border="0"
><A HREF="../index.html"
><IMG SRC="../../gx/navbar/toc.jpg" align="middle"
ALT="[ Table Of Contents ]" border="0"></A
><A HREF="../lg_answer.html"
><IMG SRC="../../gx/dennis/answertoc.jpg" align="middle"
ALT="[ Answer Guy Current Index ]" border="0"></A></td>
<td align="center" valign="center"><A HREF="../lg_answer.html#greeting"><img align="middle"
src="../../gx/dennis/smily.gif" alt="greetings" border="0"></A> &nbsp;
<A HREF="../../tag/bios.html">Meet&nbsp;the&nbsp;Gang</A> &nbsp;
<A HREF="1.html">1</A> &nbsp;
<A HREF="2.html">2</A> &nbsp;
<A HREF="3.html">3</A> &nbsp;
<A HREF="4.html">4</A> &nbsp;
<A HREF="5.html">5</A> &nbsp;
<A HREF="6.html">6</A> &nbsp;
<A HREF="7.html">7</A> &nbsp;
<A HREF="8.html">8</A>
</td>
<td align="left" valign="center"><A HREF="../../tag/kb.html"
><IMG SRC="../../gx/dennis/answerpast.jpg" align="middle"
ALT="[ Index of Past Answers ]" border="0"></A
><IMG ALT="" SRC="../../gx/navbar/right.jpg" align="middle"
WIDTH="14" HEIGHT="45" BORDER="0"></td></tr></table>
</p>
<!-- end tagnav ::::::::::::::::::::::::::::::::::::::::::::::::::::-->
<!--endcut ========================================================= -->
<P> <hr>
<!--startcut ======================================================= -->
<CENTER>
<!-- *** BEGIN navbar *** -->
<!-- *** END navbar *** -->
</CENTER>
</p>
<!--endcut ========================================================= -->
<!--startcut ======================================================= -->
</BODY></HTML>
<!--endcut ========================================================= -->