This is useful when you want to treat output to stderr from bash (and any children) differently to the prompt. Logically these are different and should be split anyway. An example of treating these differently is making all output to stderr a different colour. diff -aru bash-2.05/bashline.c bash-pb/bashline.c --- bash-2.05/bashline.c Tue Mar 6 18:36:07 2001 +++ bash-pb/bashline.c Thu Jul 12 22:12:47 2001 @@ -216,7 +216,8 @@ rl_terminal_name = get_string_value ("TERM"); rl_instream = stdin; - rl_outstream = stderr; + //rl_outstream = stderr; + rl_outstream = prompt_FILE; /* Allow conditional parsing of the ~/.inputrc file. */ rl_readline_name = "Bash"; diff -aru bash-2.05/general.c bash-pb/general.c --- bash-2.05/general.c Wed Feb 28 18:23:24 2001 +++ bash-pb/general.c Thu Jul 12 22:37:59 2001 @@ -292,7 +292,7 @@ #endif /* __BEOS__ */ void -check_dev_tty () +check_dev_tty (FILE** tty_FILE) { int tty_fd; char *tty; @@ -306,7 +306,10 @@ return; tty_fd = open (tty, O_RDWR|O_NONBLOCK); } - close (tty_fd); + if (tty_FILE) + *tty_FILE = fdopen(tty_fd, "w"); + else + close (tty_fd); } /* Return 1 if PATH1 and PATH2 are the same file. This is kind of diff -aru bash-2.05/general.h bash-pb/general.h --- bash-2.05/general.h Wed Feb 14 21:53:05 2001 +++ bash-pb/general.h Thu Jul 12 22:47:19 2001 @@ -21,6 +21,8 @@ #if !defined (_GENERAL_H_) #define _GENERAL_H_ +#include + #include "stdc.h" #include "bashtypes.h" @@ -218,7 +220,7 @@ extern int check_identifier __P((WORD_DESC *, int)); extern int sh_unset_nodelay_mode __P((int)); -extern void check_dev_tty __P((void)); +extern void check_dev_tty __P((FILE** tty_FILE)); extern int same_file (); /* too many problems with prototype */ extern int move_to_high_fd __P((int, int, int)); extern int check_binary_file __P((unsigned char *, int)); diff -aru bash-2.05/print_cmd.c bash-pb/print_cmd.c --- bash-2.05/print_cmd.c Tue Apr 3 20:05:26 2001 +++ bash-pb/print_cmd.c Thu Jul 12 22:15:26 2001 @@ -314,22 +314,22 @@ WORD_LIST *w; char *t, *x; - fprintf (stderr, "%s", indirection_level_string ()); + fprintf (prompt_FILE, "%s", indirection_level_string ()); for (w = list; w; w = w->next) { t = w->word->word; if (t == 0 || *t == '\0') - fprintf (stderr, "''%s", w->next ? " " : ""); + fprintf (prompt_FILE, "''%s", w->next ? " " : ""); else if (sh_contains_shell_metas (t)) { x = sh_single_quote (t); - fprintf (stderr, "%s%s", x, w->next ? " " : ""); + fprintf (prompt_FILE, "%s%s", x, w->next ? " " : ""); free (x); } else - fprintf (stderr, "%s%s", t, w->next ? " " : ""); + fprintf (prompt_FILE, "%s%s", t, w->next ? " " : ""); } - fprintf (stderr, "\n"); + fprintf (prompt_FILE, "\n"); } static void @@ -586,10 +586,10 @@ debug_print_cond_command (cond) COND_COM *cond; { - fprintf (stderr, "DEBUG: "); + fprintf (prompt_FILE, "DEBUG: "); command_string_index = 0; print_cond_command (cond); - fprintf (stderr, "%s\n", the_printed_command); + fprintf (prompt_FILE, "%s\n", the_printed_command); } #endif @@ -600,24 +600,24 @@ char *arg1, *arg2; { command_string_index = 0; - fprintf (stderr, "%s", indirection_level_string ()); - fprintf (stderr, "[[ "); + fprintf (prompt_FILE, "%s", indirection_level_string ()); + fprintf (prompt_FILE, "[[ "); if (invert) - fprintf (stderr, "! "); + fprintf (prompt_FILE, "! "); if (type == COND_UNARY) { - fprintf (stderr, "%s ", op->word); - fprintf (stderr, "%s", (arg1 && *arg1) ? arg1 : "''"); + fprintf (prompt_FILE, "%s ", op->word); + fprintf (prompt_FILE, "%s", (arg1 && *arg1) ? arg1 : "''"); } else if (type == COND_BINARY) { - fprintf (stderr, "%s", (arg1 && *arg1) ? arg1 : "''"); - fprintf (stderr, " %s ", op->word); - fprintf (stderr, "%s", (arg2 && *arg2) ? arg2 : "''"); + fprintf (prompt_FILE, "%s", (arg1 && *arg1) ? arg1 : "''"); + fprintf (prompt_FILE, " %s ", op->word); + fprintf (prompt_FILE, "%s", (arg2 && *arg2) ? arg2 : "''"); } - fprintf (stderr, " ]]\n"); + fprintf (prompt_FILE, " ]]\n"); } #endif /* COND_COMMAND */ @@ -629,11 +629,11 @@ { WORD_LIST *w; - fprintf (stderr, "%s", indirection_level_string ()); - fprintf (stderr, "(( "); + fprintf (prompt_FILE, "%s", indirection_level_string ()); + fprintf (prompt_FILE, "(( "); for (w = list; w; w = w->next) - fprintf (stderr, "%s%s", w->word->word, w->next ? " " : ""); - fprintf (stderr, " ))\n"); + fprintf (prompt_FILE, "%s%s", w->word->word, w->next ? " " : ""); + fprintf (prompt_FILE, " ))\n"); } #endif diff -aru bash-2.05/shell.c bash-pb/shell.c --- bash-2.05/shell.c Tue Mar 27 15:25:51 2001 +++ bash-pb/shell.c Thu Jul 12 22:53:51 2001 @@ -188,6 +188,7 @@ int dump_translatable_strings; /* Dump strings in $"...", don't execute. */ int dump_po_strings; /* Dump strings in $"..." in po format */ int wordexp_only = 0; /* Do word expansion only */ +int split_stderr = 0; /* Don't print prompt/command line to stderr */ /* Some long-winded argument names. These are obviously new. */ #define Int 1 @@ -212,6 +213,7 @@ #if defined (RESTRICTED_SHELL) { "restricted", Int, &restricted, (char **)0x0 }, #endif + { "tty-prompt", Int, &split_stderr, (char **)0x0 }, { "verbose", Int, &echo_input_at_read, (char **)0x0 }, { "version", Int, &do_version, (char **)0x0 }, { "wordexp", Int, &wordexp_only, (char **)0x0 }, @@ -240,6 +242,7 @@ static char *local_pending_command; static FILE *default_input; +FILE *prompt_FILE; static int parse_long_options (); static int parse_shell_options (); @@ -304,7 +307,7 @@ if (code) exit (2); - check_dev_tty (); + check_dev_tty (&prompt_FILE); #ifdef __CYGWIN__ _cygwin32_check_tmp (); @@ -386,6 +389,12 @@ { login_shell++; login_shell = -login_shell; + } + + if (!split_stderr) + { + fclose(prompt_FILE); + prompt_FILE = stderr; } /* All done with full word options; do standard shell option parsing.*/ diff -aru bash-2.05/shell.h bash-pb/shell.h --- bash-2.05/shell.h Sat Oct 14 22:33:01 2000 +++ bash-pb/shell.h Thu Jul 12 22:17:14 2001 @@ -18,6 +18,7 @@ with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ +#include #include "config.h" #include "bashjmp.h" @@ -105,3 +106,5 @@ }; extern struct user_info current_user; + +extern FILE *prompt_FILE;