3

I am running unit tests in a bash shell, which can take some time to finish, and those tests print output as they run. I want this output to be printed, and I also want the output to be stored in a variable. However, I want these things to be done concurrently if possible, like the tee command does when writing to a file. Perhaps tee works in this case too…

So I am currently doing this:

output=$(ginkgo -r -cover)
echo "$output"

However, this obviously won't print the unit test output until all the tests have run. So how can I get the output to print as the tests run while also storing that output in a variable?

Josh Correia
  • 3,807
  • 3
  • 33
  • 50
Alex Parker
  • 1,533
  • 3
  • 16
  • 38

2 Answers2

9
output=$(ginkgo -r -cover | tee /dev/fd/2)

You can use tee to send stdout to both stdout and stderr. stdout is captured into your variable, stderr is printed.

jbch
  • 166
  • 3
  • 1
    Thanks. As a follow up, how can I determine whether `ginkgo` failed. `$?` is going to print 0 either way in this situation. – Alex Parker Nov 29 '17 at 19:42
  • 2
    `$( )` runs its contents in a subshell, so `PIPESTATUS` will not be available from the parent shell. But you can have the subshell propagate the pipe status as *its* exit status with `output=$(ginkgo -r -cover | tee /dev/fd/2; exit ${PIPESTATUS[0]})` – Gordon Davisson Nov 29 '17 at 20:02
4

If your shell is Bash:

ginkgo -r -cover | tee ginkgo.out
output="$(< ginkgo.out)" && rm ginkgo.out

You may want to consider |& instead of | if you want to capture the standard error stream too. You may want to dispense with the rm if you would like to keep the output file.

If you don't like temporary files and you are running interactively,

output="(ginkgo -r -cover |& tee /dev/tty)"
AlexP
  • 4,370
  • 15
  • 15
  • 1
    Thanks for the suggestion. I thought of this, but was hoping for a method that doesn't involve a temporary file. – Alex Parker Nov 29 '17 at 19:27
  • 1
    @AlexP, how about an approach that uses named pipes? It's more flexible than addressing /dev/tty directly – Pavel Nov 29 '17 at 19:31