2

I'm trying to hide all the stderr from users running an interactive BASH script but keep the errors in a log file. However, simple stderr redirection quite unexpectedly hides some BASH output as well that should go to stdout instead. Have tried this on two systems and got the same results (one has GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu) and the other is on MacOS X).

I have a lingering suspicion that it could be caused by the exec replacing the shell... but another built-in (times) works as expected and outputs to stdout!

An example:

#!/bin/bash

exec 2>>file_log

echo This will be printed to stdout, as expected

ls ThereIsNoSuchFileOnEarth # this will go to “file_log”, as expected

read –p 'User would never see this prompt and it would go to file_log. Totally unexpected.' –r -e test

species=”Daleks Raxacoricofallapatorians Judoon”

select enemy in $species;
do
     # …code omitted as the user would never see the list. It would go into file_log again!
done
2
  • Note your code has "curly" quotes, not plain single/double quotes. Aug 14, 2018 at 15:17
  • Thanks for the heads-up @glennjackman, that was just a typo (I was writing this code by hand here) :)
    – Alexander
    Aug 14, 2018 at 15:19

2 Answers 2

4

The prompts from read and select are supposed to go to Standard Error, as they are prompts presumably for user interaction and not actual output. This allows you to run tool.sh > tool.out and still use read and select to collect information from the user without "contaminating" the actual output.

Standard Output is meant to be the typical output of a program, ideally such that it could be piped into Standard Input of another with neither fuss, nor muss.

This is also why curl, for example, presents its download progress on Standard Error rather than Standard Output; you can curl http://www.example.com/path/to/file > file and only the contents of file is displayed (and therefore redirected into file, while informational data are displayed using standard error.

6
  • For select, it's explicitly documented to use stderr: "The set of expanded words is printed on the standard error output stream,...". For read, I can't see it mentioned in the online documentation.
    – ilkkachu
    Aug 14, 2018 at 15:19
  • That's odd, my manual states, for read -p the following in relevant part: Display prompt on standard error... The bash manual, SHELL BUILTIN COMMANDS section, on read, under the -p option.
    – DopeGhoti
    Aug 14, 2018 at 15:22
  • Ok good, the man page has it then. I can't see it here, though: gnu.org/software/bash/manual/html_node/Bash-Builtins.html
    – ilkkachu
    Aug 14, 2018 at 15:23
  • I wonder whether a pull request can be submitted for that bug (:
    – DopeGhoti
    Aug 14, 2018 at 15:29
  • Thanks @DopeGhoti for a perfect answer! I knew it! It must have been an expected behaviour and not a bug :)
    – Alexander
    Aug 16, 2018 at 7:50
2

If you use exec to redirect stderr for the whole shell, this affects the whole shell.

You either cannot use exec to redirect the whole stderr, or you need to call something like:

read .... 2> /dev/tty

to have the builtins in question create readable output for stderr.

2
  • Yes, thanks, I've been thinking abou this "workaround" as well but wanted to understand the reason behind the madness... Thanks for the answer (unfortunately I can't upvote due to low rep)!
    – Alexander
    Aug 16, 2018 at 7:51
  • 2
    Oh wait now I can :) Upvoted :)
    – Alexander
    Aug 16, 2018 at 7:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .