Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I am trying to redirect all output from bash (prompt, user input, results) to a file

Example:

/bin/bash > file.txt 2>&1

I thought that would work, but I'm not getting the prompt. Can anyone tell me what I'm doing wrong?

share|improve this question
add comment

migrated from stackoverflow.com Sep 15 '11 at 22:15

This question came from our site for professional and enthusiast programmers.

4 Answers

Bash outputs the prompt only in interactive mode. I.e. it is normally output to the terminal (/dev/tty on linux). That is neither /dev/stdout or /dev/stdin :)

Now, I'm not sure but I can imagine that bash will allow limited interactive mode when there isn't a fully functional tty. In that case I'd expect the prompt to be written to stdout. I haven't tested that.

Nice Proof Of Concept:

(for a in some set of words; do echo $a > /dev/tty; done) 2>&1 > /dev/null

will just output 1..10 as if there wasn't redirection. Like the prompt, output is directly sent to the terminal (which will fail if there isn't one)

HINT: if you wanted everything to be collected look at

share|improve this answer
    
Added hints on how to potentially get more bash output into a pipe –  sehe Sep 15 '11 at 14:37
    
seq is a highly nonstandard external command, and shouldn't be used in this manner. If you're using bash, do something like for x in {1..10}, or for ((x=1; x<=10; x++)) instead. –  Chris Down Sep 15 '11 at 23:25
    
@Chris: good point, thanks for the heads up –  sehe Sep 15 '11 at 23:30
add comment

To trick bash into thinking it's in interactive mode (although stdout is not being sent to a terminal) you may use the already mentioned script command.

(
exec 1> >(tee bashlog.txt) 2>&1
script -q /dev/null /bin/bash -l
)

# alternative without script command
(
# bash: no job control in this shell
exec 1> >(tee bashlog.txt) 2>&1
/bin/bash -il
)
share|improve this answer
    
+1 for high level of detail –  sehe Sep 17 '11 at 15:27
add comment

The simplest way to do it would be

bash -i >/tmp/logfile 2>&1

Bash will write everything to /tmp/logfile and keep executing commands as you type them, but nothing will be displayed in the terminal. You can make it exit just as you exit your terminal session - by pressing Ctrl+D or typing exit.

Notice that if you run the same thing without stderr redirection, you will only have the greeting message logged to the file, all the rest will work in your current terminal. So the answer to your question about stream to which bash outputs its prompt (and all the following commands) seems to be: stderr.

Oh yes, and the -i parameter simply forces bash to run in interactive mode. Don't listen to those people - you don't need any magic tricks to do that ;)

share|improve this answer
    
+1 for use of <sub> to format. I just learned something new today. :D –  Chris K Jan 13 at 20:43
add comment

The prompt is written to stderr as truss (on Solaris here) shows:

$ truss -ft write -p 10501
10501:  write(2, " d", 1)               = 1
10501:  write(2, " a", 1)               = 1
10501:  write(2, " t", 1)               = 1
10501:  write(2, " e", 1)               = 1
10501:  write(2, "\n", 1)               = 1
10521:  write(1, " S a t u r d a y ,   S e".., 46)  = 46
10501:      Received signal #18, SIGCLD [caught]
10501:        siginfo: SIGCLD CLD_EXITED pid=10521 status=0x0000
10501:  write(2, " $  ", 2)             = 2
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.