How to `paste` stdin next to stderr?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
0
down vote

favorite












Usually paste prints two named (or equivalent) files in adjacent columns like this:



paste <(printf '%sn' a b) <(seq 2)


Output:



a 1
b 2


But when the two files are /dev/stdin and /dev/stderr, it doesn't seem to work the same way:



seq 2 | tee >(sed 's/^/e/' > /dev/stderr) | paste /dev/stdin /dev/stderr


Output:



1 e1
e2
^C


It hangs -- ^C means pressing Control-C to quit.



Changing the | to a ; also doesn't work:



seq 2 | tee >(sed 's/^/e/' > /dev/stderr) ; paste /dev/stdin /dev/stderr


Output:



1
2
e1
e2
^C


Also hangs -- ^C means pressing Control-C to quit.



Desired output:



1 e1
2 e2


Can it be done using paste? If not, why not?










share|improve this question























  • Similar: tee + cat: use an output several times and then concatenate results
    – Stéphane Chazelas
    11 hours ago










  • Possible duplicate of Split an input for different command and combine the result
    – Stéphane Chazelas
    11 hours ago






  • 2




    You're never redirecting stderr, so it will probably be the terminal device if you run that from a terminal. Reading from a terminal device (like your paste /dev/stderr does) reads what you type on the keyboard, writing to it (like your tee /dev/stderr does) sends it for display by the terminal emulator.
    – Stéphane Chazelas
    11 hours ago










  • Could you tell us exactly what you want to do? You can go with for i in $(seq 2); do echo -n "$i " > /dev/stdout; echo e$i > /dev/stderr; done and you will get the same effect
    – mrc02_kr
    11 hours ago






  • 1




    See also: Why can't I read /dev/stdout with a text editor
    – agc
    9 hours ago















up vote
0
down vote

favorite












Usually paste prints two named (or equivalent) files in adjacent columns like this:



paste <(printf '%sn' a b) <(seq 2)


Output:



a 1
b 2


But when the two files are /dev/stdin and /dev/stderr, it doesn't seem to work the same way:



seq 2 | tee >(sed 's/^/e/' > /dev/stderr) | paste /dev/stdin /dev/stderr


Output:



1 e1
e2
^C


It hangs -- ^C means pressing Control-C to quit.



Changing the | to a ; also doesn't work:



seq 2 | tee >(sed 's/^/e/' > /dev/stderr) ; paste /dev/stdin /dev/stderr


Output:



1
2
e1
e2
^C


Also hangs -- ^C means pressing Control-C to quit.



Desired output:



1 e1
2 e2


Can it be done using paste? If not, why not?










share|improve this question























  • Similar: tee + cat: use an output several times and then concatenate results
    – Stéphane Chazelas
    11 hours ago










  • Possible duplicate of Split an input for different command and combine the result
    – Stéphane Chazelas
    11 hours ago






  • 2




    You're never redirecting stderr, so it will probably be the terminal device if you run that from a terminal. Reading from a terminal device (like your paste /dev/stderr does) reads what you type on the keyboard, writing to it (like your tee /dev/stderr does) sends it for display by the terminal emulator.
    – Stéphane Chazelas
    11 hours ago










  • Could you tell us exactly what you want to do? You can go with for i in $(seq 2); do echo -n "$i " > /dev/stdout; echo e$i > /dev/stderr; done and you will get the same effect
    – mrc02_kr
    11 hours ago






  • 1




    See also: Why can't I read /dev/stdout with a text editor
    – agc
    9 hours ago













up vote
0
down vote

favorite









up vote
0
down vote

favorite











Usually paste prints two named (or equivalent) files in adjacent columns like this:



paste <(printf '%sn' a b) <(seq 2)


Output:



a 1
b 2


But when the two files are /dev/stdin and /dev/stderr, it doesn't seem to work the same way:



seq 2 | tee >(sed 's/^/e/' > /dev/stderr) | paste /dev/stdin /dev/stderr


Output:



1 e1
e2
^C


It hangs -- ^C means pressing Control-C to quit.



Changing the | to a ; also doesn't work:



seq 2 | tee >(sed 's/^/e/' > /dev/stderr) ; paste /dev/stdin /dev/stderr


Output:



1
2
e1
e2
^C


Also hangs -- ^C means pressing Control-C to quit.



Desired output:



1 e1
2 e2


Can it be done using paste? If not, why not?










share|improve this question















Usually paste prints two named (or equivalent) files in adjacent columns like this:



paste <(printf '%sn' a b) <(seq 2)


Output:



a 1
b 2


But when the two files are /dev/stdin and /dev/stderr, it doesn't seem to work the same way:



seq 2 | tee >(sed 's/^/e/' > /dev/stderr) | paste /dev/stdin /dev/stderr


Output:



1 e1
e2
^C


It hangs -- ^C means pressing Control-C to quit.



Changing the | to a ; also doesn't work:



seq 2 | tee >(sed 's/^/e/' > /dev/stderr) ; paste /dev/stdin /dev/stderr


Output:



1
2
e1
e2
^C


Also hangs -- ^C means pressing Control-C to quit.



Desired output:



1 e1
2 e2


Can it be done using paste? If not, why not?







shell io-redirection stderr paste






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 9 hours ago

























asked 11 hours ago









agc

4,3221935




4,3221935











  • Similar: tee + cat: use an output several times and then concatenate results
    – Stéphane Chazelas
    11 hours ago










  • Possible duplicate of Split an input for different command and combine the result
    – Stéphane Chazelas
    11 hours ago






  • 2




    You're never redirecting stderr, so it will probably be the terminal device if you run that from a terminal. Reading from a terminal device (like your paste /dev/stderr does) reads what you type on the keyboard, writing to it (like your tee /dev/stderr does) sends it for display by the terminal emulator.
    – Stéphane Chazelas
    11 hours ago










  • Could you tell us exactly what you want to do? You can go with for i in $(seq 2); do echo -n "$i " > /dev/stdout; echo e$i > /dev/stderr; done and you will get the same effect
    – mrc02_kr
    11 hours ago






  • 1




    See also: Why can't I read /dev/stdout with a text editor
    – agc
    9 hours ago

















  • Similar: tee + cat: use an output several times and then concatenate results
    – Stéphane Chazelas
    11 hours ago










  • Possible duplicate of Split an input for different command and combine the result
    – Stéphane Chazelas
    11 hours ago






  • 2




    You're never redirecting stderr, so it will probably be the terminal device if you run that from a terminal. Reading from a terminal device (like your paste /dev/stderr does) reads what you type on the keyboard, writing to it (like your tee /dev/stderr does) sends it for display by the terminal emulator.
    – Stéphane Chazelas
    11 hours ago










  • Could you tell us exactly what you want to do? You can go with for i in $(seq 2); do echo -n "$i " > /dev/stdout; echo e$i > /dev/stderr; done and you will get the same effect
    – mrc02_kr
    11 hours ago






  • 1




    See also: Why can't I read /dev/stdout with a text editor
    – agc
    9 hours ago
















Similar: tee + cat: use an output several times and then concatenate results
– Stéphane Chazelas
11 hours ago




Similar: tee + cat: use an output several times and then concatenate results
– Stéphane Chazelas
11 hours ago












Possible duplicate of Split an input for different command and combine the result
– Stéphane Chazelas
11 hours ago




Possible duplicate of Split an input for different command and combine the result
– Stéphane Chazelas
11 hours ago




2




2




You're never redirecting stderr, so it will probably be the terminal device if you run that from a terminal. Reading from a terminal device (like your paste /dev/stderr does) reads what you type on the keyboard, writing to it (like your tee /dev/stderr does) sends it for display by the terminal emulator.
– Stéphane Chazelas
11 hours ago




You're never redirecting stderr, so it will probably be the terminal device if you run that from a terminal. Reading from a terminal device (like your paste /dev/stderr does) reads what you type on the keyboard, writing to it (like your tee /dev/stderr does) sends it for display by the terminal emulator.
– Stéphane Chazelas
11 hours ago












Could you tell us exactly what you want to do? You can go with for i in $(seq 2); do echo -n "$i " > /dev/stdout; echo e$i > /dev/stderr; done and you will get the same effect
– mrc02_kr
11 hours ago




Could you tell us exactly what you want to do? You can go with for i in $(seq 2); do echo -n "$i " > /dev/stdout; echo e$i > /dev/stderr; done and you will get the same effect
– mrc02_kr
11 hours ago




1




1




See also: Why can't I read /dev/stdout with a text editor
– agc
9 hours ago





See also: Why can't I read /dev/stdout with a text editor
– agc
9 hours ago











1 Answer
1






active

oldest

votes

















up vote
0
down vote













Why you can't use /dev/stderr as a pipeline



The problem isn't with paste, it's with the available file descriptors. All commands have one input descriptor, /dev/stdin, and two outputs, /dev/stdout and /dev/stderr.



When you run



seq 2 | tee >(sed ... >/dev/stderr)


with nothing after it, the /dev/stdout of tee is the console -- a write-only file descriptor, where command output usually appears. The output of sed has been redirected to /dev/stderr, which points to that same console (because you haven't redirected it with eg. 2>...). When you add another command to the pipeline...



seq 2 | tee >(sed ... >/dev/stderr) | paste /dev/stdin /dev/stderr


the second | connects the /dev/stdout of tee to /dev/stdin of paste. But there's no equivalent read descriptor to connect up to /dev/stderr/. sed output still goes to the console.
Meanwhile, when paste can reads its first argument (/dev/stdin) fine, but when it attempts to read from the second filename, /dev/stderr, that's the console, which cannot be read and hangs.



Your link Why can't I read /dev/stdout with a text editor? is still relevant here because those same restrictions apply to /dev/stderr.



How to make a second pipeline



It appears you want to use tee to "split" some output, process one of the copies with an additional command, and paste the two back together. That means two concurrent pipes, one for each column. The shell pipeline ... | ... provides one of those. bash has created another for the >(...), but that's an anonymous FIFO -- you can't retrieve its name for use in another command. So you're going to need to create another, using a name you do know:



mkfifo RHS
seq 2 | tee >(sed 's/^/e/' > RHS ) | paste /dev/stdin RHS


If this is for use in a script, you may need to make that FIFO in a temporary directory, and remove it after use. bash will automatically clear up the one it created.






share|improve this answer




















    Your Answer







    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "106"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f474232%2fhow-to-paste-stdin-next-to-stderr%23new-answer', 'question_page');

    );

    Post as a guest






























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote













    Why you can't use /dev/stderr as a pipeline



    The problem isn't with paste, it's with the available file descriptors. All commands have one input descriptor, /dev/stdin, and two outputs, /dev/stdout and /dev/stderr.



    When you run



    seq 2 | tee >(sed ... >/dev/stderr)


    with nothing after it, the /dev/stdout of tee is the console -- a write-only file descriptor, where command output usually appears. The output of sed has been redirected to /dev/stderr, which points to that same console (because you haven't redirected it with eg. 2>...). When you add another command to the pipeline...



    seq 2 | tee >(sed ... >/dev/stderr) | paste /dev/stdin /dev/stderr


    the second | connects the /dev/stdout of tee to /dev/stdin of paste. But there's no equivalent read descriptor to connect up to /dev/stderr/. sed output still goes to the console.
    Meanwhile, when paste can reads its first argument (/dev/stdin) fine, but when it attempts to read from the second filename, /dev/stderr, that's the console, which cannot be read and hangs.



    Your link Why can't I read /dev/stdout with a text editor? is still relevant here because those same restrictions apply to /dev/stderr.



    How to make a second pipeline



    It appears you want to use tee to "split" some output, process one of the copies with an additional command, and paste the two back together. That means two concurrent pipes, one for each column. The shell pipeline ... | ... provides one of those. bash has created another for the >(...), but that's an anonymous FIFO -- you can't retrieve its name for use in another command. So you're going to need to create another, using a name you do know:



    mkfifo RHS
    seq 2 | tee >(sed 's/^/e/' > RHS ) | paste /dev/stdin RHS


    If this is for use in a script, you may need to make that FIFO in a temporary directory, and remove it after use. bash will automatically clear up the one it created.






    share|improve this answer
























      up vote
      0
      down vote













      Why you can't use /dev/stderr as a pipeline



      The problem isn't with paste, it's with the available file descriptors. All commands have one input descriptor, /dev/stdin, and two outputs, /dev/stdout and /dev/stderr.



      When you run



      seq 2 | tee >(sed ... >/dev/stderr)


      with nothing after it, the /dev/stdout of tee is the console -- a write-only file descriptor, where command output usually appears. The output of sed has been redirected to /dev/stderr, which points to that same console (because you haven't redirected it with eg. 2>...). When you add another command to the pipeline...



      seq 2 | tee >(sed ... >/dev/stderr) | paste /dev/stdin /dev/stderr


      the second | connects the /dev/stdout of tee to /dev/stdin of paste. But there's no equivalent read descriptor to connect up to /dev/stderr/. sed output still goes to the console.
      Meanwhile, when paste can reads its first argument (/dev/stdin) fine, but when it attempts to read from the second filename, /dev/stderr, that's the console, which cannot be read and hangs.



      Your link Why can't I read /dev/stdout with a text editor? is still relevant here because those same restrictions apply to /dev/stderr.



      How to make a second pipeline



      It appears you want to use tee to "split" some output, process one of the copies with an additional command, and paste the two back together. That means two concurrent pipes, one for each column. The shell pipeline ... | ... provides one of those. bash has created another for the >(...), but that's an anonymous FIFO -- you can't retrieve its name for use in another command. So you're going to need to create another, using a name you do know:



      mkfifo RHS
      seq 2 | tee >(sed 's/^/e/' > RHS ) | paste /dev/stdin RHS


      If this is for use in a script, you may need to make that FIFO in a temporary directory, and remove it after use. bash will automatically clear up the one it created.






      share|improve this answer






















        up vote
        0
        down vote










        up vote
        0
        down vote









        Why you can't use /dev/stderr as a pipeline



        The problem isn't with paste, it's with the available file descriptors. All commands have one input descriptor, /dev/stdin, and two outputs, /dev/stdout and /dev/stderr.



        When you run



        seq 2 | tee >(sed ... >/dev/stderr)


        with nothing after it, the /dev/stdout of tee is the console -- a write-only file descriptor, where command output usually appears. The output of sed has been redirected to /dev/stderr, which points to that same console (because you haven't redirected it with eg. 2>...). When you add another command to the pipeline...



        seq 2 | tee >(sed ... >/dev/stderr) | paste /dev/stdin /dev/stderr


        the second | connects the /dev/stdout of tee to /dev/stdin of paste. But there's no equivalent read descriptor to connect up to /dev/stderr/. sed output still goes to the console.
        Meanwhile, when paste can reads its first argument (/dev/stdin) fine, but when it attempts to read from the second filename, /dev/stderr, that's the console, which cannot be read and hangs.



        Your link Why can't I read /dev/stdout with a text editor? is still relevant here because those same restrictions apply to /dev/stderr.



        How to make a second pipeline



        It appears you want to use tee to "split" some output, process one of the copies with an additional command, and paste the two back together. That means two concurrent pipes, one for each column. The shell pipeline ... | ... provides one of those. bash has created another for the >(...), but that's an anonymous FIFO -- you can't retrieve its name for use in another command. So you're going to need to create another, using a name you do know:



        mkfifo RHS
        seq 2 | tee >(sed 's/^/e/' > RHS ) | paste /dev/stdin RHS


        If this is for use in a script, you may need to make that FIFO in a temporary directory, and remove it after use. bash will automatically clear up the one it created.






        share|improve this answer












        Why you can't use /dev/stderr as a pipeline



        The problem isn't with paste, it's with the available file descriptors. All commands have one input descriptor, /dev/stdin, and two outputs, /dev/stdout and /dev/stderr.



        When you run



        seq 2 | tee >(sed ... >/dev/stderr)


        with nothing after it, the /dev/stdout of tee is the console -- a write-only file descriptor, where command output usually appears. The output of sed has been redirected to /dev/stderr, which points to that same console (because you haven't redirected it with eg. 2>...). When you add another command to the pipeline...



        seq 2 | tee >(sed ... >/dev/stderr) | paste /dev/stdin /dev/stderr


        the second | connects the /dev/stdout of tee to /dev/stdin of paste. But there's no equivalent read descriptor to connect up to /dev/stderr/. sed output still goes to the console.
        Meanwhile, when paste can reads its first argument (/dev/stdin) fine, but when it attempts to read from the second filename, /dev/stderr, that's the console, which cannot be read and hangs.



        Your link Why can't I read /dev/stdout with a text editor? is still relevant here because those same restrictions apply to /dev/stderr.



        How to make a second pipeline



        It appears you want to use tee to "split" some output, process one of the copies with an additional command, and paste the two back together. That means two concurrent pipes, one for each column. The shell pipeline ... | ... provides one of those. bash has created another for the >(...), but that's an anonymous FIFO -- you can't retrieve its name for use in another command. So you're going to need to create another, using a name you do know:



        mkfifo RHS
        seq 2 | tee >(sed 's/^/e/' > RHS ) | paste /dev/stdin RHS


        If this is for use in a script, you may need to make that FIFO in a temporary directory, and remove it after use. bash will automatically clear up the one it created.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 6 hours ago









        JigglyNaga

        3,112626




        3,112626



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f474232%2fhow-to-paste-stdin-next-to-stderr%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            Peggy Mitchell

            Palaiologos

            The Forum (Inglewood, California)