0

I redirected standard error of bash command to a file and bash prompt got redirected. But when i print the content of file, it was empty. Where did the bash prompt go?

image

and again when i redirect stdout of bash to a file, it redirected the output and and not the prompt as expected but while printing the content of file, there were some characters form the prompt too. How?

enter image description here

value of $PS1 and $PROMPT_COMMAND:

enter image description here

2
  • For future reference, please don't post images of text. The link leads to our sister site but the reasoning applies here as well. Commented Jun 24, 2021 at 12:54
  • Thank you. I didn't know that. From now on i won't post image of text.
    – Kapil
    Commented Jun 25, 2021 at 13:55

2 Answers 2

4

bash 2>file explained

Interactive Bash does use stderr to print the prompt (and the command line while it's being edited).

bash 2>file does not save any of these to the file because it's not interactive. Non-interactive bash does not print any prompt, does not evaluate PROMPT_COMMAND; there is no command line editing provided by readline and if the input is from the terminal then only basic editing provided by the terminal driver is available.

While Bash Reference Manual claims "an interactive shell is one started without non-option arguments […] and whose input and output are both connected to terminals […]", my tests indicate it's not about stdin and stdout (as I would interpret "input and output") but about stdin and stderr. I mean these start non-interactive shells:

  • <script bash
  • bash 2>file

and these start interactive shells:

  • bash >file
  • bash

With bash 2> file you started a non-interactive shell. bash did not print any prompt, that's why the file turned out to be empty.

If you did bash -i 2>file then you would enforce an interactive shell, you would send prompt(s) to the file. Try it, but expect no echo of what you type, because this goes to the file.

Similarly if you redirected stderr of already running interactive bash (exec 2>file) then you would also capture its prompt(s).


bash >file explained (in your case)

As stated above, bash >file starts an interactive shell. One sees prompts in the terminal, one can edit commands. Stdout is redirected as one expects.

In your case file contained extra strings because your PROMPT_COMMAND is what it is.

PROMPT_COMMAND
If this variable is set, and is an array, the value of each set element is interpreted as a command to execute before printing the primary prompt ($PS1). If this is set but not an array variable, its value is used as a command to execute instead.

(source)

This is your PROMPT_COMMAND:

printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"

When executed, it prints to stdout. If stdout is redirected to a file, it will print to the file.

When sent to a sufficiently advanced terminal (terminal emulator), a byte sequence resulted from \033]0;…\007 changes icon name and window title. In other words normally your terminal intercepts this output and uses it to configure itself rather then printing anything.

Probably you had deliberately set this PROMPT_COMMAND and forgot (or wasn't aware in the first place) it prints to stdout.

When stdout is redirected to a regular file then there will be no terminal to intercept the sequence and what printf from PROMPT_COMMAND prints will get to the file. You observed exactly this. It seems bat tried to do something with the ESC characters (from \033), ]0; and the first letter of kapil, that's why you saw apil; BEL characters resulting from \007 were shown as ^G. It doesn't matter. The point is what you didn't expect came from printf in your PROMPT_COMMAND.

If I were you and I wanted to keep this PROMPT_COMMAND, I would set it to printf … >&2. Normally stdout and stderr of an interactive shell go to the same terminal, so it doesn't matter which one printf (executed from PROMPT_COMMAND) prints to. But when you redirect stdout as you did, you don't want "garbage" from PROMPT_COMMAND.

2
  • +1. Good explanation.
    – harrymc
    Commented Jun 23, 2021 at 21:12
  • Thank you. Superb explanation btw.
    – Kapil
    Commented Jun 24, 2021 at 3:50
1

Redirecting will result in a file that is difficult to read (or use) because of the binary characters in the prompt.

For getting a readable complete copy of your session, you could use script(1) to log everything sent to the terminal:

$ script
Script started, file is typescript
$ # do your work
...
$ # then exit with ^D
$ exit
Script done, file is typescript
1
  • First paragraph isn't really correct as bash, in common with other shells, won't write a prompt at all unless it is running as an interactive instance. script works because it creates a pseudo tty (like screen) and sends output not only to the terminal but also the typescript file Commented Sep 12, 2023 at 16:27

You must log in to answer this question.

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