我尝试从bash执行命令并检索stdout,stderr和退出代码。 到目前为止,一切都很好。
问题开始于该程序具有交互式输入。
更确切地说,我执行“ git commit”(不带-m),并执行“ GNU nano”以放置提交消息。
如果我只是简单地使用:
git commit
或
exec git commit
我可以看到提示,但看不到stdout / stderr。
如果我使用
output=`git commit 2>&1`
或
output=$(git commit 2>&1)
我可以检索stdout / stderr,但是看不到提示。 我仍然可以按ctrl + X放弃git commit。
我的第一次尝试是通过函数调用,脚本最终挂在黑屏上,并且ctrl + x / ctrl + c不起作用。
function Execute()
{
if [[ $# -eq 0 ]]; then
echo "Error : function 'Execute' called without argument."
exit 3
fi
local msg=$("$@ 2>&1")
local error=$?
if [[ $error -ne 0 ]]; then
echo "Error : '"$(printf '%q ' "$@")"' return '$error' error code."
echo "$1 message :"
echo "$msg"
echo
exit 1
fi
}
Execute git commit
我开始耗尽想法/知识。我想做的事是不可能的吗?还是有我不知道的方法?
答案 0 :(得分:0)
尝试使用此方法,将每行输出处理到stdout或stderr并根据内容重定向:
#!/bin/env bash
foo() {
printf 'prompt: whos on first?\n' >&2
printf 'error: uh-oh\n' >&2
}
var=$(foo 2>&1 | awk '{print | "cat>&"(/prompt/ ? 2 : 1)}' )
echo "var=$var"
$ ./tst.sh
prompt: whos on first?
var=error: uh-oh
或仅处理stderr的代码:
#!/bin/env bash
foo() {
printf 'prompt: whos on first?\n' >&2
printf 'error: uh-oh\n' >&2
}
var=$(foo 2> >(awk '{print | "cat>&"(/prompt/ ? 2 : 1)}') )
echo "var=$var"
$ ./tst.sh
prompt: whos on first?
var=error: uh-oh
awk命令根据内容将其输入拆分为stderr或stdout,只有stdout保存在变量var
中。我不知道您的提示会出现在stderr还是stdout上,或者您真的想去哪里,但是要进行按摩以适合您想要去stdout vs stderr的内容以及想要在变量vs中看到的内容,以及打印到屏幕。您只需要在提示中包含一些内容即可识别出来,这样就可以将提示与其他stdout和stderr分开,并在其他所有内容都重定向到stdout时将提示打印到stderr。
或者,这是一个将第一行(无论内容如何)打印到stderr进行显示,并将其他所有内容打印到stdout进行捕获的版本:
$ cat tst.sh
#!/bin/env bash
foo() {
printf 'prompt: whos on first?\n' >&2
printf 'error: uh-oh\n' >&2
}
var=$(foo 2>&1 | awk '{print | "cat>&"(NR>1 ? 1 : 2)}' )
echo "var=$var"
$ ./tst.sh
prompt: whos on first?
var=error: uh-oh