How to redirect output of a command to a file when the command will prompt user inputs?
Solution 1:
Your command works and properly redirects the output to the file abc.txt
.
The question is how is your script asking the input data and how are you running the script?
Let we see with two examples:
# Script_1.sh # 1
echo Please, enter your firstname and lastname # 2
read FN LN # 3
echo "Hi! $LN, $FN !" # 4
and
# Script_2.sh # 5
read -p "Enter a comment " CM # 6
echo "You said $CM" # 7
If you run /bin/bash Script1.sh > abc.txt
you will not see the question "Please enter..." on your tty. If you will give the expected input from keyboard you will find the output of line #2 and #4 in your abc.txt
file.
If you run /bin/bash Script2.sh > abc.txt
you will see the question "Enter a comment ", but you will find in the abc.txt
file only the output of the line #7.
Note: if you run the Script2,sh in a subshell
(bash Script2.sh 2>&1)> abc.txt
you will not see any output on tty and you will find all in the abc.txt
file.
If you run it with
bash Script2.sh 2>ccc.txt 1>ddd.txt`
you will find the Standard output (line #7) in ddd.txt
and the standard error (line #6) inccc.txt
.
If you want to redirect only part of your command output you have to modify your script.
One of the way to do it, is to create a function in which to move the part of the script that will generate the interesting output (see below). Then you can call this function from the main part of your script (where it was originally the code that you moved into the function) redirecting only that output to the log file:
Part_To_Redirect(){
: # all that you want
}
# ... Main part of the script
# point where it was the part that generates the output
Part_to_Redirect "$@" > abc.txt # this to store only that part in the file
# Part_to_Redirect "$@" >> abc.txt # this to append that part in the file
# ...
You should even find useful tee
that
redirects the output to multiple files, copies standard input to standard output and also to any files given as arguments.
the_command | tee abc.txt # To redirect Standard output
or
the_command 2>&1 | tee abc.txt # To redirect err in out and both in the file
In this case you will have the normal outputs of your command on the tty, but at the same time you will save a copy in the log file abc.txt
. It should be cosy in your case if you use read -p
as in the script2 the invocation the_command | tee abc.txt
.
Notes and references:
Adding "$@"
you can pass all the argument of your script to the function.
You may find interesting to read more about bashredirection from many sources on internet.
- As suggested by Scott in his comment there is a wiki answer of Unix SE: a good starting point.
- A must the
man bash
or the bash manual. - I found useful the redirection chapter of bash-hackers where you can find links to obsolete uses too.
- You can refer to the Advanced Bash-Scripting Guide, chapter 20 too.
Solution 2:
By default, only STDOUT
is redirected and/or piped. What you want is to leave STDOUT
alone, and have whatever is passed via STDIN
redirected.
If editing the_command
is an option, you could make sure that the question is output to STDERR
instead (that should dump it to screen regardless of any redirects), and then have it echo whatever the user types back to screen via STDOUT
.
Solution 3:
There are usually 2 important output pipes: STDOUT
(for regular output) and STDERR
(for error messages).
The problem here is, that the "regular" output of the command and the text of the prompt are both written to STDOUT
, so they are always put into the same location. When you use your redirection, it just takes the whole STDOUT
, including the prompt.
If rewriting (as suggested in another answer by Jarmund) of the command is not possible, maybe the command has an additional option/flag (like --output
), that can specify some output file instead of using the redirection?