mainThe GNU Bourne-Again SHell - Support: sr #110461, mkpipe for bash


sr #110461: mkpipe for bash

Submitter:  None
Submitted:  Tue 16 Mar 2021 05:57:18 PM UTC
Category:  None Priority:  5 - Normal
Severity:  1 - Wish Status:  Wont Do
Privacy:  Public Assigned to:  None
Originator Email:  -email is unavailable- Open/Closed:  Open
Operating System:  None
* Mandatory Fields

Add a New Comment Rich Markup

Mon 19 Apr 2021 09:45:19 AM UTC, comment #3: 

> Well, you have a need based on your specific circumstances.

If a collection of stdout and stderr in non intermixed manner is a specific circumstances, then ok. But, imho, redirection to a variable is more needed(and more conceptual) than strange thing like &> and &>> .

P.S. shell mkpipe has a race condition. We made a binary that resolve this - . May be this will be useful for somebody.

Thu 25 Mar 2021 07:08:39 PM UTC, comment #2: 

Well, you have a need based on your specific circumstances. You should be able to take your requirements and write a loadable builtin to do what you need it to do.

Then we see whether or not that translates into a general need.

Chet Ramey <chet>
Group administrator
Tue 16 Mar 2021 06:03:48 PM UTC, comment #1: 

Of course in read_all should be "local" command:

# Read all data from a pipe
# $1 - variable name
        eval "local ${1}_"

        while eval "read -t0 ${1}_"; do
                eval "read ${1}_"
                eval "$1=\"\${${1}}\${${1}_}

Tue 16 Mar 2021 05:57:18 PM UTC, original submission:  

Hi, all.

There is a need for something like a mkpipe bash builtin.
Sometimes there is need to execute some commands in a subshell and we need to collect an output from stdout and stderr(and sometimes from even more file descriptors; e.g. our script need to collect an output from 4 fd - 1, 2, 3 and 4 - where 1 is used for a data, 2 for errors, 3 is used for error which should be sent to a client and 4 for debug messages). Thus, simple:

data=$(commands here)

isn't enough for this case. We can use files as a temporary storage for an output:

({commands here} >data.out 2>err.out 3>err_client.out 4>debug.out)

But with read-only fs this isn't work.

Now we use the next workaround:

# Create a pipe
#  $1 - read fd
#  $2 - write fd
        local PID1 PID2
        local FD_READ FD_WRITE

        tail -f /dev/null | tail -f /dev/null &
        PID1=`jobs -p %+`
        eval "exec $FD_READ</proc/$PID2/fd/0 $FD_WRITE>/proc/$PID1/fd/1"
        disown $PID1
        kill $PID1 $PID2

Example of use:

        echo "DBG: $@" >&4

# Read all data from a pipe
# $1 - variable name
        while eval "read -t0 ${1}_"; do
                eval "read ${1}_"
                eval "$1=\"\${${1}}\${${1}_}
exec 4>&2
dbg_out start

mkpipe 5 6
# ...
dbg_out inner msg
dbg_out inner msg again
} 4>&6)

read_all line <&5
echo "$line"

dbg_out finish



(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:

No files currently attached


Depends on the following items: None found

Items that depend on this one: None found


Carbon-Copy List
  • -email is unavailable- added by chet (Posted a comment)
  • -email is unavailable- added by None (Submitted the item)

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.


    Follows 1 latest change.

    Date Changed by Updated Field Previous Value => Replaced by
    2021-03-25 chet StatusNone Wont Do

    Back to the top

    Powered by Savane 3.12