All unix tools use stderr for error and informational messages, which includes prompting. Standard output is reserved for actual data. However, as you have seen, you are free to swap them around with redirections
As I said earlier, If you need to undo a file descriptor's redirection, you need to store the descriptor's original destination in another descriptor. I demonstrated how to do that in my first post in this thread (though it's possible you missed it as I kept editing what I included, again, sorry for that), Why stderr file descriptor redirection makes ksh's "select" construct hang. Post: 302419560.
Regards,
Alister
---------- Post updated at 05:01 PM ---------- Previous update was at 04:36 PM ----------
That 2>&1 suggestion was from an earlier version of my original post. You probably don't want to do that. The redirections applied to select apply to all commands executed within the select as well. Doing 2>&1 after the select's "done" will send the stderr of all commands to stdout, not just the select's prompt.
Either abandon the notion of globally redirecting stderr, or accept that you may have to append per-command redirections. In this case, if you don't want the standard error of the command executed by select to redirect to the same place as the select prompt (say, to a file instead of the screen), you will need to override the global stderr for the select statment. Then, within the select, you will need to restore the global redirect per command or command block. It's a mess.
A possible alternative, which logs all standard error (including select prompting), but allows the prompt to be seen on screen (along with any other error messages), can be relatively cleanly implemented from outside the script:
exec 3>&1
script.sh 2>&1 1>&3 | tee standard_err.log 1>&2
exec 3>&-
That works by using file descriptor 3 to store the original destination of stdout. Then when script.sh is executed, its stdout will be redirected into the pipe. However, we don't want that. We want its stderr to go into the pipe, so we redirect script.sh's stderr into the pipe, by copying stdout's current destination. Then, we point stdout to its old location which is stored in fd 3. The order of operations is very much significant. If "2>&1" and "1>&3" were reversed, nothing would flow into the pipe. Also, it's key to realize that redirections to/from a pipe occur before other redirections.
If that's confusing to you (which is understandable), the best advice I can give you is to read up a bit on redirections and tinker with them until the concept clicks. It's one of the more difficult concepts in sh scripting (particularly if the person isn't familiar with the kernel's notion of file descriptors and how they interact with system calls like open, close, dup, dup2, fork, and exec).
Regards,
Alister