2

I am running git push command in bash which generates some errors.

RESPONSE=$(git push "$target" --all | grep "error:" || true)

generates an output on the screen but variable $RESPONSE is empty

If I change the command to do this:

RESPONSE=$(git push "$target" --all 2>&1 | grep "error:" || true)

command runs silently but actually captures needed error in $RESPONSE

echo $RESPONSE

error: failed to push some refs to 'ssh://git@git.test.test.com:7999/test/test-test.git'

I really need to run this git push command in a way that it would hold the error above in $RESPONSE yet generate the entire output on the screen.

Running

RESPONSE=$(git push "$target" --all 2>&1 | tee -a log | grep "error:" || true) did not help, unless I am missing something.

Dzerlig
  • 247
  • 2
  • 10
  • 1
    Possible duplicate of [How do I write stderr to a file while using "tee" with a pipe?](https://stackoverflow.com/questions/692000/how-do-i-write-stderr-to-a-file-while-using-tee-with-a-pipe) – mkrieger1 Nov 11 '18 at 17:18
  • But possibly there is a better way if you use the lower-level "plumbing" Git commands for this kind of scripting instead of the "porcelain" commands intended for human interaction. – mkrieger1 Nov 11 '18 at 17:19
  • See: [How to set a variable to the output `git push` command](https://unix.stackexchange.com/q/346557/74329) – Cyrus Nov 11 '18 at 17:30
  • 1
    See also: https://stackoverflow.com/questions/12451278/capture-stdout-to-a-variable-but-still-display-it-in-the-console – mkrieger1 Nov 11 '18 at 17:40
  • Possible duplicate of [Capture stdout to a variable but still display it in the console](https://stackoverflow.com/questions/12451278/capture-stdout-to-a-variable-but-still-display-it-in-the-console) – tink Nov 11 '18 at 18:35

2 Answers2

4

One solution is to use tee; just not exactly the way you showed. Taking it step by step will perhaps make the solution easier to understand:

git push "$target" --all

will send the error you want to STDERR. That's why you added 2>&1, to redirect STDERR to STDOUT.

git push "$target" --all 2>&1

Then your pipeline (grep, etc.) is able to pick it up and eventually the variable capture is able to see it when you do

RESPONSE=$(git push "$target" --all 2>&1 | grep "error:" || true)

But because the error is no longer going to STDERR, and STDOUT is now being captured instead of sent to the screen, the output disappears.

So what you want to use tee for, is to put the output on both STDERR (for the screen) and STDOUT (for your pipeline and eventual variable capture).

RESPONSE=$(git push "$target" --all 2>&1 |tee >(cat 1>&2) | grep "error:" || true)

This will likely work as you intend, but be aware that everything you see on the screen - all output from the git command, error or otherwise - is now being passed on STDERR.

There aren't many practical reasons why this would be better than the answer about capturing to the variable and then echoing the variable (per miimote's answer), but if for some reason the non-sequential command structure seems better to you, this is a way to do it.

Mark Adelsberger
  • 42,148
  • 4
  • 35
  • 52
  • Thank you so much! That worked! You represent of best of StackOverflow community where you do explain how everything works. It was exceptionally helpful. I wish I can give you more points. Much, much appreciated! – Dzerlig Nov 11 '18 at 19:30
1

The first line

RESPONSE=$(git push "$target" --all | grep "error:" || true)

stores the response of the command in the var RESPONSE. So it is done in bash for any construction like VAR=$(command). If exists an error the var is empty but generates an output for the user. If you add 2>&1, you are saying the same but if exists an error the output is the file $1, in your case the var $RESPONSE. You could do this

RESPONSE=$(git push "$target" --all 2>&1 | grep "error:" || true); echo $RESPONSE

You can read more about command substitution and redirections

miimote
  • 373
  • 2
  • 12
  • thanks for your response! I really need to be able to do both at the same time, just can't figure out the right command to display the output and store the error in $RESPONSE. – Dzerlig Nov 11 '18 at 18:20
  • So your comment really just restates the question but doesn't really answer it, unless I am missing something – Dzerlig Nov 11 '18 at 18:40