CBlew
CBlew

Reputation: 721

In Bash, how to print to stdout when it’s already redirected?

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?

Upvotes: 1

Views: 1698

Answers (1)

Charles Duffy
Charles Duffy

Reputation: 295766

Answering The Original Question

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


Advice Re: Best-Practice Usage

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:

Upvotes: 2

Related Questions