I am writing a Bash function, say func() { … }
, that interactively asks user a few questions and then runs a certain command.
The prize here is the stdout
of said command, and I expect users to call my function like this: func >outfile
, to capture the command’s output in a file.
My question is, how do I print those interactive questions to stdout
without polluting the useful output?
In other words: within a function, if stdout
has been potentially redirected by the caller, how do I write to the ‘original’ stdout
(the terminal), temporarily ignoring caller’s redirect?
Do I have to resort to using stderr
for output that semantically doesn’t belong there?
Create a backup of your original stdout at the point in time when your function is defined, and you can use it at invocation time.
exec {myfunc_stdout_fd}>&1
myfunc() {
echo "Content sent to stdout as defined at invocation time"
echo "Content sent to original stdout" >&"$myfunc_stdout_fd";
}
...whereafter:
myfunc_out=$(myfunc)
...stores Content sent to stdout as defined at invocation time
in myfunc_out
, and immediately writes Content sent to original stdout
to the stdout that was defined when the function definition took place.
See this running in an online interpreter at https://ideone.com/HwHRJ7
Prompts are conventionally written to stderr on UNIX, so for prompting-related purposes, retaining the original stdout isn't generally called for. Prompting on stderr is what read -p
does; what bash itself does (like other shells); etc. This is appropriate, as POSIX defines stderr as the appropriate stream for "diagnostic output", which is a category that includes status about what the program is doing at the moment (whether it's ready for more input, f/e).
See also: