287 lines
11 KiB
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 ©</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>
|
|
<A HREF="1.html">1</A>
|
|
<A HREF="2.html">2</A>
|
|
<A HREF="3.html">3</A>
|
|
<A HREF="4.html">4</A>
|
|
<A HREF="5.html">5</A>
|
|
<A HREF="6.html">6</A>
|
|
<A HREF="7.html">7</A>
|
|
<A HREF="8.html">8</A>
|
|
<A HREF="9.html">9</A>
|
|
<A HREF="10.html">10</A>
|
|
<A HREF="11.html">11</A>
|
|
<A HREF="12.html">12</A>
|
|
<A HREF="13.html">13</A>
|
|
<A HREF="14.html">14</A>
|
|
<A HREF="15.html">15</A>
|
|
<A HREF="16.html">16</A>
|
|
<A HREF="17.html">17</A>
|
|
<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 ========================================================= -->
|