Micha Niskin

Wednesday May 20, 2009
Category  

Suppose you have some process that produces output to both stdout and stderr, like curl, for example, and you need to be able to parse both streams simultaneously.

Normally this is a pain with bash. Bash doesn’t have the handy ‘|&’ redirection that the c shells have. You can still accomplish your task, but it won’t be pretty:

res=$((((curl -sLv -X GET http://ubergibson.com \
        |sed 's/^/OUT /' && echo) 3>&2 2>&1 1>&3) \
        |sed 's/^/ERR /' && echo) 2>&1)

Basically what is going on here is this: the first layer of parentheses runs curl, processing stdout with sed to prepend ‘OUT ‘ to each line of output. Then stderr and stdout file descriptors are swapped, which allows us to pipe the old stderr (new stdout) to the second sed process, which prepends ‘ERR ‘ to each line.

Finally, stderr is duped to stdout and the whole mess is stored in the ‘res’ variable. Extracting the stderr and stdout from this variable is straightforward and left as an exercise to the reader ;)

Comment

  1. dpopC9 vgfzhywfwepj, [url=http://nfsvfgfsrvoj.com/]nfsvfgfsrvoj[/url], [link=http://ahdlptddbssf.com/]ahdlptddbssf[/link], http://pxkhqymrphhw.com/

    fawwzjomhjd · Nov 20, 01:23 PM · #

  2. Does this do what you want?
    $ ls /root /usr 2>>(wc -l) >>(wc -l)
    13
    1

    /root is not readable, hence the 1, /usr has 12 entries plus itself.

    You can then combine them back like so:
    $ { ls /root /usr 2>>(wc -l) >>(wc -l) } | wc -l
    2

    Janos Barbero · Jan 6, 07:10 PM · #

  3. DkPUbH

    fhSDXJt · Feb 2, 07:30 PM · #