10

I'm new to bash and I can not for the life of me figure out how to run a certain command, suppose ./fff and print regular stdouts before stderr (I'm confused about the meaning myself)

for example

$ printf "I am a\ndrill\n" > fff; 
$ cat fff nofile fff nofile fff

I am a
drill
cat: nofile: No such file or directory
I am a
drill
cat: nofile: No such file or directory
I am a
drill

needs to print like:

I am a
drill
I am a
drill
I am a
drill
cat: nofile: No such file or directory
cat: nofile: No such file or directory

I understand that I need to redirect my output first to a file and then append the error to the same file however this is the output I get for

$ cat ./foo nofile ./foo nofile ./foo <<< $(touch fin) > see 2>> see 

I am a
drill
I am a
drill
I am a
drill
ectory
cat: nofile: No such file or directory
2
  • 2
    Did cat really replace "a" by "some"? Jan 15 '18 at 13:06
  • oh dang I might have messed up the string. I'll edit it right away @DmitryGrigoryev
    – MeOw
    Jan 15 '18 at 15:44
19

You'll need to hold the stderr output somewhere anyway to be able to display it at the end.

A file comes to mind:

fff 2> file; cat file >&2

Or memory (here using sponge from moreutils):

{ fff 2>&1 >&3 3>&- | sponge >&2 3>&-; } 3>&1
  • {...} 3>&1: within {...} file descriptor (fd) 3 points to the same resource as the original stdout (so we can use it to restore stdout for fff).
  • fff <redirs> | sponge <redirs>, fff and sponge started concurrently (with <redirs> applied independently) with fff's stdout going to a pipe, and sponge's stdin being the other end of the pipe.
  • 2>&1: fd 2 of fff (stderr) points to the same thing as on 1: the pipe at this point, so fff's error go to sponge via that pipe.
  • >&3: now stdout points to the original stdout (redirect back to what it was)
  • 3>&-: we close fd 3 which fff doesn't need
  • sponge accumulates its input and only displays it (on its stdout which has been redirected with >&2 to the same resource as stderr) after it has detected eof on its stdin (assumed to be when fff terminates and has already written all its output on its stdout).

If sponge is not installed, you can replace it with perl -0777 -pe ''. With -pe '', perl reads one record at a time from its input and writes it on stdout. -0777 is the slurp mode where the (only one in that case) record is the whole input.

7
  • I still haven't advanced too much into unix as of yet (taking a course right now), but the first line about "holding the stderr somewhere" gave me the idea to do this (according to what I needed to do anyway) cat ./foo nofile ./foo nofile ./foo > fout.txt 2>> ferr.txt; cat fout.txt ferr.txt
    – MeOw
    Jan 15 '18 at 3:28
  • 2
    @MeOw: That’s fine, but, as the third line of Stéphane’s answer shows, you don’t need to save the stdout; just do cat foo nofile foo nofile foo 2> ferr.txt; cat ferr.txt.  (And you probably don t want to use >>.)  Also, Stéphane makes the excellent point that you should probably do cat ferr.txt >&2 to write the stderr information to the stderr. Jan 15 '18 at 5:04
  • @G-Man you're right, >> was going to append everything, Noticed it quite later. I still, unfortunately, don't have the capability as of yet to understand what @Stéphane fully said, (I tried) but I will refer to it again once I do. Also, cat foo nofile foo nofile foo 2> ferr.txt; cat ferr.txt prints out the stderr only once and not twice according to how many times I had invoked a non-existent file nofile (unless I'm being dumb and doing sth really wrong)?
    – MeOw
    Jan 15 '18 at 7:23
  • Well, either there’s something wrong with your system, or you’re doing something wrong.  I just did that command (replacing foo with the name of a short file that I already had lying around) and I got cat: nofile: No such file or directory twice in my ferr.txt file.  Are you doing it all as one command, or as five separate ones?  What do you get if you do cat nofile nofile 2> ferr.txt (leaving out the good file)? Jan 15 '18 at 15:40
  • @G-Man I was doing it all cat foo nofile foo nofile foo. Absolutely no changes. I'll check the cat nofile nofile later sometime. It's probably the cloud9 that's messing up.. I'll try again and update.
    – MeOw
    Jan 15 '18 at 15:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.