-1

I have a few shell scripts that are intended to work together. The first script (script1.sh) calls the next script in a sub-shell. The second script (script2.sh) needs to "return" something for the first script to use. I need the last line that is echoed in the second script. However, when I use it this way, any output via echo in the second script does not get output to the terminal. I want all output from the first and second (and third, and fourth, ...) to be output to the terminal, but also written to a log file.

script1.sh:

#!/bin/sh

func_one() {
   RESULT=$(./script2.sh | tail -1)
   echo "RESULT: $RESULT"
}

func_one | tee log_file.log

script2.sh:

#!/bin/sh

echo "Hello"
echo "World!"

Attempt 1 output:

$ ./script1.sh
RESULT: World!
$

log_file.log contents:

RESULT: World!

If I try to redirect output in the second script, then it outputs to the terminal, but not to the log file:

script2.sh:

#!/bin/sh

echo "Hello" >&2
echo "World!" >&2

Attempt 2 output:

$ ./script1.sh
Hello
World!
RESULT:

log_file.log contents:

RESULT:

I also tried outputting to terminal and tee on the same line in script 1:

func_one >&2 | tee log_file.log

But that gives the same result as the first attempt.

What I would like is to have both output to the terminal AND written to the .log file: (if it was working correctly)

$ ./script1.sh
Hello
World!
RESULT: World!
$

log_file.log contents:

Hello
World!
RESULT: World!

How can I go about getting this result? Also, it would be preferred to NOT use bash, as a few of our machines we are going to be running this on do not have bash.

I've looked here: How do I get both STDOUT and STDERR to go to the terminal and a log file? but that didn't help in my case.

Ebad
  • 131
  • 11

1 Answers1

0

To get all the output of script2.sh sent to the terminal without interfering with the work of script1.sh, try this modification of script1.sh:

$ cat script1.sh
#!/bin/bash

func_one() {
   RESULT=$(./script2.sh | tee >(cat >&2) | tail -1)
   echo "RESULT: $RESULT"
}

func_one | tee log_file.log

Here, the first tee command makes sure that all script2.sh output appears, via stderr, on the terminal. To do this, process substitution is needed (and this, in turn, requires an upgrade from sh to bash).

The output is:

$ ./script1.sh
Hello
World!
RESULT: World!

Variation

This is the same as the above except that we don't touch stderr (you may want to reserve that errors). Here, we create an additional file descripter, 3, to duplicate stdout:

#!/bin/bash

exec 3>&1
func_one() {
   RESULT=$(./script2.sh | tee >(cat >&3) | tail -1)
   echo "RESULT: $RESULT"
}

func_one | tee log_file.log
John1024
  • 109,961
  • 14
  • 137
  • 171