1

I'm trying to send all output to a log, with stderr also displaying in the console.

..with the log entries in order and some method to send comments to the log+console (same as stderr).

exec &> log

For instance, this doesn't work:

#!/bin/bash

exec 2> >(tee log) 2>&1 > build.log

echo "Yes 1"
ugh "No 1"
echo "Yes 2"
ugh "No 2"
echo "Message to user" 3>&1

The examples I'm finding here and elsewhere either put them out of order or redirect both to log and console.

None of the examples send all output to the log - with stderr and 'special messages' also displayed on screen...


Solution

Chris solved this in his answer below. This is the adapted solution:

#!/bin/bash

exec 3> >(tee -a log)
exec 4>>log
exec >&4 2>&3

# Out: To log.
echo "I'm standard output."

# Error: To log and console.
ugh "command not found"

# Message: To log and console.
echo "Message to user." >&3

This writes the to the log / console as the given comment suggests.

1

I'm assuming this is to be done in a script? If so, this should do what you want, I think. stdout will be sent only to out.txt. stderr will be sent to the console and to err.txt

#!/bin/bash
exec 3> >(tee ./err.txt)
exec 4>./out.txt
exec >&4 2>&3

echo "I'm normal text!"    # only in out.txt
echo "I'm an error!" >&2   # in err.txt and on console

Edit: I'm disturbingly pleased with myself for this little script, and I'm not quite sure why.

Edit 2: To write both streams to the same file, simply use the same filename in both places. In theory, this could rarely cause a loss of ordering between stdout and stderr; in practice it's close enough. (See my rambling comment below for more.)

  • Works (adjusted to write to one file)! If I don't have the reputation, will someone upvote this? – Pear Apr 9 '15 at 3:11
  • If you use the same filename for both streams, you will get that effect. The message ordering will be preserved in effectively all cases. That being said, in some extremely rare cases, absolute ordering may be lost on a very small number of cases (if the CPU schedules the various threads just right and messages come from both pipes at exactly the same time and the tee is preempted by a stdout write that completes before tee resumes...). In practice, since I/O is pretty atomic, I would consider the occurrence of this to be effectively never. – Chris Apr 9 '15 at 3:11
  • Also, even if you can't upvote, you should be able to accept it as an answer, correct? With the checkmark icon. – Chris Apr 9 '15 at 3:15
  • Yep lol - Accepted, and thank you!! Updated my question to reflect your answer adjusted. – Pear Apr 9 '15 at 3:21
0

You can swap the stdout and the stderr stream. see this example:

ps aux 3>&1 1>&2 2>&3 | grep init

Check out this link for more detail.

  • Tried, but no-go for what I'm trying to do, thank you though! – Pear Apr 9 '15 at 3:24

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.