old-www/LDP/LG/issue54/tag/11.html

287 lines
11 KiB
HTML

<!--startcut ======================================================= -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<META NAME="generator" CONTENT="lgazmail v1.3D.j">
<TITLE>The Answer Guy 54: Embedding Newlines in Shell and Environment Values</TITLE>
</HEAD><BODY BGCOLOR="#FFFFFF" TEXT="#000000"
LINK="#3366FF" VLINK="#A000A0">
<!-- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
<P> <hr>
<!-- *** BEGIN navbar *** :::::::::::::::::::::::::::::::::::::::::::::::: -->
<p align="center">
<A HREF="../lg_bytes54.html"><IMG ALT="[ Prev ]"
SRC="../../gx/navbar/prev.jpg"
WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A>
<IMG ALT="" SRC="../../gx/navbar/left.jpg"
WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom" >
<A HREF="../index.html"><IMG ALT="[ Table of Contents ]"
SRC="../../gx/navbar/toc.jpg"
WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A>
<A HREF="../../index.html"><IMG ALT="[ Front Page ]"
SRC="../../gx/navbar/frontpage.jpg"
WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A>
<A HREF="../../faq/index.html"><IMG ALT="[ FAQ ]"
SRC="../../gx/navbar/faq.jpg"
WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A>
<IMG ALT="" SRC="../../gx/navbar/right.jpg"
WIDTH="15" HEIGHT="45" ALIGN="bottom" >
<A HREF="../lg_tips54.html"><IMG ALT="[ Next ]"
SRC="../../gx/navbar/next.jpg"
WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A>
<!-- *** END navbar *** :::::::::::::::::::::::::::::::::::::::::::::::::: -->
</p>
<P> <hr> <P>
<!-- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
<center>
<H1><A NAME="answer">
<img src="../../gx/dennis/qbubble.gif" alt="(?)"
border="0" align="middle">
<font color="#B03060">The Answer Guy</font>
<img src="../../gx/dennis/bbubble.gif" alt="(!)"
border="0" align="middle">
</A></H1>
<BR>
<H4>By James T. Dennis,
<a href="mailto:linux-questions-only@ssc.com">linux-questions-only@ssc.com</a><BR>
LinuxCare,
<A HREF="http://www.linuxcare.com/">http://www.linuxcare.com/</A>
</H4>
</center>
<p><hr><p>
<!-- endcut ======================================================= -->
<!-- begin 11 -->
<H3 align="left"><img src="../../gx/dennis/qbubble.gif"
height="50" width="60" alt="(?) " border="0"
>Embedding Newlines in Shell and Environment Values</H3>
<p><strong>From Mark Chitty on Mon, 08 May 2000
</strong></p>
<!-- ::
Embedding Newlines in Shell and Environment Values
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:: -->
<P><STRONG>
Hi Jim,
</STRONG></P>
<P><STRONG>
Thanks for the solution. I had gone down a different path but this has
cleared up that little conundrum !! I seems obvious now that you point it
out.
</STRONG></P>
<P><STRONG>
Your reply is much appreciated.
</STRONG></P>
<P><STRONG>
Oh yes, if you ever write a book let me know. I'll buy it !!
</STRONG></P>
<P><STRONG>
cheers,
mark
</STRONG></P>
<BLOCKQUOTE><IMG SRC="../../gx/dennis/bbub.gif" ALT="(!)"
HEIGHT="28" WIDTH="50" BORDER="0"
>
Actually I have written one book <TT>---</TT> it's _Linux_System_Administration_
(New Riders Publishing, 1999, with M Carling and Stephen Degler).
(<A HREF="http://www.linuxsa.com"
>http://www.linuxsa.com</A>).
</BLOCKQUOTE>
<BLOCKQUOTE>
However, I might have to write a new one on shell scripting. Oddly
enough it seems to be a topic of growing interest despite the ubiquity
of PERL, Python, and many other scripting languages.
</BLOCKQUOTE>
<BLOCKQUOTE>
In fact, one thing I'd love to do is learn enough Python to write a
book that covers all three (comparatively). Python seems to be a very
good language for learning/teaching programming. I've heard several
people refer to Python as "executable psuedo-code."
</BLOCKQUOTE>
<BLOCKQUOTE>
Despite the availability of other scripting languages, the basic shell,
AWK, and related tools are compelling. They are what we use when we
work at the command line. Often enough we just want our scripts to
"do what we would do manually" <TT>---</TT> and then to add just a bit of
logic and error checking around that.
</BLOCKQUOTE>
<BLOCKQUOTE>
Extra tidbit:
</BLOCKQUOTE>
<BLOCKQUOTE><BLOCKQuote>
I recently found a quirky difference between Korn shell ('93) and
bash. Consider the following:
</BLOCKQuote></BLOCKQUOTE>
<BLOCKQUOTE><BLOCKQUOTE><CODE>
echo foo | read bar; echo $bar
</CODE></BLOCKQUOTE></BLOCKQUOTE>
<BLOCKQUOTE>
... whenever you see a "|" operator in a shell command sequence
you should understand that there is implicitly a subshell (new
process) that is created (forked) on one side of it or the other.
</BLOCKQUOTE>
<BLOCKQUOTE>
Of course other processes (including subshells) cannot affect
the values of your shell variables. So the sequence above
consists of three commands (echo the string "foo", read something
and assign it to a shell variable named "bar", and echo the
value of (read the $ dereferencing operator as "the value of")
the shell named "bar"). It consists of two processes. One
on one side of the pipe, and the other on the other side of the
pipe. At the semicolon the shell waits for the completion of
any programs and commands that precede it, and then continues
with a new command sequence in the current shell.
</BLOCKQUOTE>
<BLOCKQUOTE>
The question becomes whether the subshell was created on the
left or the right of the | in this command. In bash it is
clearly created on the right. The 'read' command executes in
a subshell. That then exits (thus "forgetting" its variable
and environment heaps). Thus $bar is unaffected after the
semicolon.
</BLOCKQUOTE>
<BLOCKQUOTE>
In ksh '93 and in zsh the subshell seems to be created to the
left of the pipe. The 'read' command is executed in the
current shell and thus the local value of "bar" is affected.
Then the subsequent access to that shell variable does
reflect the new value.
</BLOCKQUOTE>
<BLOCKQUOTE>
As far as I know the POSIX spec is silent on this point. It
may even be that ksh '93 and zsh are in violation of the
spec. If so, the spec is wrong!
</BLOCKQUOTE>
<BLOCKQUOTE>
It is very useful to be able to parse a set of command
outputs into a local list of shell variables. Note that
for a single variable this is easy:
</BLOCKQUOTE>
<BLOCKQUOTE><BLOCKQuote>
bar=$(echo foo)
</BLOCKQuote></BLOCKQUOTE>
<BLOCKQUOTE>
or:
</BLOCKQUOTE>
<BLOCKQUOTE><BLOCKQuote>
bar=`echo foo`
</BLOCKQuote></BLOCKQUOTE>
<BLOCKQUOTE>
... are equivalent expressions and they work just
fine.
</BLOCKQUOTE>
<BLOCKQUOTE>
However, when we want to read the outputs into several values,
and especially when we want to do so using the IFS environment
value to parse these values then we have to resort of inordinate
amounts of fussing in bash while ksh '93 and newer versions of
zsh allow us to do something like:
</BLOCKQUOTE>
<BLOCKQUOTE><BLOCKQUOTE><CODE>
grep ^joe /etc/passwd | IFS=":" read login pw uid gid gecos home sh
</CODE></BLOCKQUOTE></BLOCKQUOTE>
<BLOCKQUOTE>
(Note the form: 'VAR=val cmd' as shown here is also a bit
obscure but handy. The value of VAR is only affected for
the duration of the following command <TT>---</TT> thus saving us the
trouble of saving the old IFS value, executing our 'read'
command and restoring the IFS).
</BLOCKQUOTE>
<BLOCKQUOTE>
BTW: If you do need to save/restore something like IFS
you must using proper quoting. For example:
</BLOCKQUOTE>
<BLOCKQUOTE><BLOCKQUOTE><CODE>
OLDIFS="$IFS"
<BR># MUST have double/soft quotes here!
<BR>IFS=:,
<BR># do stuff parsing words on colons and commas
<BR>IFS="$OLDIFS"
<BR># MUST also have double/soft quotes here!
</CODE></BLOCKQUOTE></BLOCKQUOTE>
<BLOCKQUOTE>
Anyway, I would like to do some more teaching in the
field of shell scripting. I also plan to get as good
with C and Python as I currently am with 'sh'. That'll
take at least another year or so, and a lot more practice!
</BLOCKQUOTE>
<!-- sig -->
<!-- end 11 -->
<!--startcut ======================================================= -->
<P> <hr> </p>
<H5 align="center"><a href="http://www.linuxgazette.com/copying.html"
>Copyright &copy;</a> 2000, James T. Dennis
<BR>Published in <I>The Linux Gazette</I> Issue 54 June 2000</H5>
<H6 ALIGN="center">HTML transformation by
<A HREF="mailto:star@tuxtops.com">Heather Stern</a> of
Tuxtops, Inc.,
<A HREF="http://www.tuxtops.com/">http://www.tuxtops.com/</A>
</H6>
<P> <hr>
<!-- begin tagnav ::::::::::::::::::::::::::::::::::::::::::::::::::-->
<p align="center">
<IMG ALT="" SRC="../../gx/navbar/left.jpg"
WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="middle" border="0">
<A HREF="../lg_answer54.html"
><IMG SRC="../../gx/dennis/answertoc.jpg" align="middle"
ALT="[ Answer Guy Current Index ]" border="0"></A>
<A HREF="../lg_answer54.html#greeting"><img align="middle"
src="../../gx/dennis/smily.gif" alt="greetings" border="0"></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> &nbsp;
<A HREF="9.html">9</A> &nbsp;
<A HREF="10.html">10</A> &nbsp;
<A HREF="11.html">11</A> &nbsp;
<A HREF="12.html">12</A> &nbsp;
<A HREF="13.html">13</A> &nbsp;
<A HREF="14.html">14</A> &nbsp;
<A HREF="15.html">15</A> &nbsp;
<A HREF="16.html">16</A> &nbsp;
<A HREF="17.html">17</A> &nbsp;
<A HREF="18.html">18</A>
<A HREF="../../tag/kb.html"
><IMG SRC="../../gx/dennis/answerpast.jpg" align="middle"
ALT="[ Index of Past Answers ]" border="0"></A></td>
<IMG ALT="" SRC="../../gx/navbar/right.jpg" align="middle"
WIDTH="14" HEIGHT="45" BORDER="0">
</p>
<!-- end tagnav ::::::::::::::::::::::::::::::::::::::::::::::::::::-->
<P> <hr>
<!-- *** BEGIN navbar *** :::::::::::::::::::::::::::::::::::::::::::::::: -->
<p align="center">
<A HREF="../lg_bytes54.html"><IMG ALT="[ Prev ]"
SRC="../../gx/navbar/prev.jpg"
WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A>
<IMG ALT="" SRC="../../gx/navbar/left.jpg"
WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom" >
<A HREF="../index.html"><IMG ALT="[ Table of Contents ]"
SRC="../../gx/navbar/toc.jpg"
WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A>
<A HREF="../../index.html"><IMG ALT="[ Front Page ]"
SRC="../../gx/navbar/frontpage.jpg"
WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A>
<A HREF="../../faq/index.html"><IMG ALT="[ FAQ ]"
SRC="../../gx/navbar/faq.jpg"
WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A>
<IMG ALT="" SRC="../../gx/navbar/right.jpg"
WIDTH="15" HEIGHT="45" ALIGN="bottom" >
<A HREF="../lg_tips54.html"><IMG ALT="[ Next ]"
SRC="../../gx/navbar/next.jpg"
WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A>
<!-- *** END navbar *** :::::::::::::::::::::::::::::::::::::::::::::::::: -->
</p>
<!-- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
</BODY></HTML>
<!--endcut ========================================================= -->