Advanced shell scripting question :-)

Derek D. Martin ddm+gnhlug at pizzashack.org
Thu Sep 5 14:57:33 EDT 2002


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

At some point hitherto, Kevin D. Clark hath spake thusly:
> > Any I/O gurus out there know by what mechanism this could be achieved?
> > I'm now very curious...  
> 
> You can't do with with any of the standard i/o multiplexing facilities
> (select(), poll(), etc.)

That was my conclusion as well, from perusing APitUE (Stevens).

> You could do this with threads, in a fashion.

I'd be curious as to how this would work...

> However...
> 
> > It seems to me this probably not the only
> > sort of application where you might want to process the input from
> > several descriptors in the order it was received.
> 
> ...most of the descriptors that I deal with are connected to things
> that are influenced by a certain degree of randomness (the randomness
> of a network, the randomness of a OS's scheduler, etc.).  Because of
> this, I never find myself architecting a program that would call of
> this sort of capability -- it'd be non-sensical.

I can see where that'd be true in most cases... and really this is
only a problem where you want to keep the various inputs seperate,
while at the same time joining them together.

When I initially saw Steven's original post, my first inclination was
to respond that, if one had access to the source of the program, the
better solution would be to add code to (optionally) duplicate stdout
and stderr to seperate files.  Though I was sidetracked by what seemed
(to me) to be an interesting programming problem...  But if you did
that, then, by simply running the program with some equivalent of:

  $ myprogram --stdout=/tmp/stdout --stderr=/tmp/stderr 2>&1 > /tmp/both
  $ tail -f /tmp/both

You get everything you want.  

Steven's application appears to be a script, based on what he's said
in previous posts, which also suggests he's got at least some control
over it (i.e. he could make a local copy of it for his own
purposes)...  Depending on the application, how big it is, and how
complicated its command line args are, this might be very easy to do.
If the program ordinarily does not take arguments, then it can be as
simple as just using the convention that $1=stdout and $2=stderr.
Then in your script, whenever you want to output to stdout, you just
do something like this:

  echo "Here is my output"
  echo "Here is my output" > $1

  echo -e "$0: error!\n  cant't write to file" >&2
  echo -e "$0: error!\n  cant't write to file" >$2
  
For clarity's sake, I'd probably assign $1 and $2 to different
variables that indicate their function (and because $2 and &2 look
about the same, esp. to someone with bad vision), but you get the
idea...

It strikes me that the likely reason for going through all this would
be for debugging purposes...  so one might also hardcode the paths to
the files (in an easy to modify variable), and then do something like:

  echo "Here is my output"
  if [ "$1" = "-d" ]; then
    echo "Here is my output" > $stdout_file
  fi

  echo -e "$0: error!\n  cant't write to file" >&2
  if [ "$1" = "-d" ]; then
    echo -e "$0: error!\n  cant't write to file" >$stderr_file
  fi

Or, rather than conditionalizing it, you could just set $stdout_file
and $stderr_file to /dev/null when you don't want the output...

If you can modify the source, there are all sorts of ways around the
problem...  And that's the best way to go about it, if the order of
the output matters to you.

- -- 
Derek Martin               ddm at pizzashack.org    
- ---------------------------------------------
I prefer mail encrypted with PGP/GPG!
GnuPG Key ID: 0x81CFE75D
Retrieve my public key at http://pgp.mit.edu
Learn more about it at http://www.gnupg.org
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE9d6kddjdlQoHP510RAvlAAJ9hNj2pfApScn9EIrSSxDUhoieXGwCgu4I0
YNpQe/c4f94RudnQylF7vCw=
=m73G
-----END PGP SIGNATURE-----



More information about the gnhlug-discuss mailing list