TheNewGuy
TheNewGuy

Reputation: 579

bash input/ouput to a log file

I have a bash script with below statement. I need to output both the question "Are you happy? and the answer "yes" or "no" to a log file. I'm able to get the answer to log file with "echo "$yn" >>log1.log 2>&1" but not the question (read command)

while true; do
    read -p "Are you happy? " yn
    case $yn in
        [Yy]* ) break;;
        [Nn]* ) exit;;
        * ) echo "Please answer yes or no.";;
    esac
done
echo "$yn" >>log1.log 2>&1

What I have tried: read -p "Are you okay?" yn > log.log 2>&1 This will indeed work, however when I run my scrip the question is not displayed. The only way I found is to echo "Are you happy? $yn" >>log1.log 2>&1 The problem with this is that I have several prompts with long statements, I like to keep my scripts nice and short

Upvotes: 2

Views: 1618

Answers (1)

tripleee
tripleee

Reputation: 189397

The redirect only applies to the echo. You need to add a similar redirect afther the done. (This will also redirect the error message which you echo from within case, which incidentally should go to standard error):

while true; do
    read -p "Are you happy? " yn
    case $yn in
        [Yy]* ) break;;
        [Nn]* ) exit;;
        * ) echo "Please answer yes or no." >&2;;
    esac
done >>log1.log 2>&1
echo "$yn" >>log1.log

or put the entire sequence of commands inside parenthes or braces.

{ while true; do
    read -p "Are you happy? " yn
    case $yn in
        [Yy]* ) break;;
        [Nn]* ) exit;;
        * ) echo "Please answer yes or no." >&2;;
    esac
done
echo "$yn"; } >>log1.log 2>&1

Like you discovered, and like the term should reveal, a redirection causes the output to go to another place (so a file instead of your terminal, in this case). If you want it displayed on the terminal as well, tee does that, but it's probably not suitable for interactive scripts (because you can't include standard input in the output).

tripleee$ cat >nst
#!/bin/bash
while true; do
  read -p "Are you happy? " yn
  case $yn in
    [Yy]*) break;;
    [Nn]*) exit;;
    *) echo "Please answer yes or no." >&2;;
  esac
done
echo "$yn"
^D

tripleee$ chmod +x ./nst

tripleee$ ./nst 2>&1 | tee log1.log
Are you happy? forget it
Please answer yes or no.
Are you happy? no

tripleee$ cat log1.log
Are you happy? Please answer yes or no.
Are you happy? tripleee$

Perhaps you are actually looking for the script command?

tripleee$ script typescript ./nst
Script started, output file is typescript
Are you happy? forget it
Please answer yes or no.
Are you happy? yes ma'am
yes ma'am

Script done, output file is typescript

tripleee$ nl -ba typescript
     1  Script started on Thu Oct 26 20:34:04 2017
     2  command: ./nst
     3  Are you happy? forget it
     4  Please answer yes or no.
     5  Are you happy? yes ma'am
     6  yes ma'am
     7  
     8  Script done on Thu Oct 26 20:34:11 2017

Note that the typescript file will contain any edits done by the user, i.e. typos and their correction will be included, with the various display codes used by the terminal to execute the edits.

Upvotes: 1

Related Questions