我正在bash中运行git push命令,这会产生一些错误。
RESPONSE=$(git push "$target" --all | grep "error:" || true)
在屏幕上生成输出,但变量$ RESPONSE为空
如果我更改命令来执行此操作:
RESPONSE=$(git push "$target" --all 2>&1 | grep "error:" || true)
命令以静默方式运行,但实际上捕获了$ RESPONSE中所需的错误
echo $RESPONSE
错误:无法将一些引用推送到 'ssh://git@git.test.test.com:7999 / test / test-test.git'
我真的需要以某种方式运行此git push命令,使其能够在$ RESPONSE中保存上面的错误,但会在屏幕上生成整个输出。
运行
RESPONSE=$(git push "$target" --all 2>&1 | tee -a log | grep "error:" || true)
没有帮助,除非我丢失了一些东西。
答案 0 :(得分:2)
一种解决方案是使用tee
;并不完全符合您的展示方式。逐步执行它可能会使解决方案更容易理解:
git push "$target" --all
会将您想要的错误发送给STDERR。因此,您添加了2>&1
来将STDERR重定向到STDOUT。
git push "$target" --all 2>&1
然后,您的管道(grep等)可以将其拾取,并且最终您可以在执行操作时看到变量捕获
RESPONSE=$(git push "$target" --all 2>&1 | grep "error:" || true)
但是,由于错误不再归因于STDERR,并且现在捕获了STDOUT而不是将其发送到屏幕,因此输出消失了。
因此,您要使用tee
的方法是将输出同时放在 STDERR(用于屏幕)和STDOUT(用于管道和最终变量捕获)上。
RESPONSE=$(git push "$target" --all 2>&1 |tee >(cat 1>&2) | grep "error:" || true)
这可能会按您预期的方式工作,但是请注意,您在屏幕上看到的所有内容-git
命令的所有输出,错误或其他内容-现在都将通过STDERR传递。
并没有很多实际的原因,为什么这比捕获变量然后回显变量的答案更好(根据miimote的回答),但是如果出于某种原因,非顺序命令结构对您来说似乎更好,这是一种方法。
答案 1 :(得分:1)
第一行
RESPONSE=$(git push "$target" --all | grep "error:" || true)
将命令的响应存储在变量RESPONSE
中。因此,对于VAR=$(command)
之类的任何构造,它都是以bash形式完成的。如果存在错误,则var为空,但会为用户生成输出。
如果添加2>&1
,则表示相同,但如果存在错误,则输出为文件$1
,在您的情况下为var $RESPONSE
。
你可以这样做
RESPONSE=$(git push "$target" --all 2>&1 | grep "error:" || true); echo $RESPONSE
您可以详细了解command substitution和redirections