修改zsh命令以转发错误
问题描述:
我想修改一个最近的Bash别名来转发错误。这里是别名:修改zsh命令以转发错误
alias makecclip=
"make |& tee >(sed \"s,\x1B\[[0-9;]*[a-zA-Z],,g\" |
egrep \":[0-9]+:[0-9]+: error\" | cut -d : -f1,2,3 |
head -n 1 | xargs -0 echo -n | xclip -selection clipboard &&
xclip -selection clipboard -o)
这个代码显示一个C++编译的结果,然后删除格式化和显示和到剪贴板将第一误差位置(如果有的话)。
不过,我想用这个代码:
makecclip && bin/someexecutablecreated
这虽然废墟&&
运营商,因为它始终运行斌/ someexecutablecreated即使有编译错误存在。当错误列表(保存到剪贴板和回显的东西)不为空时,如何添加对代码的修改以设置错误标志?
答
您可以使用PIPESTATUS
内部变量(该变量在非bash shell中具有其他名称)来解决您的问题。这允许具有管道传递的命令的退出状态的历史记录。
你一种高精度的,你没有使用bash
的意见,但使用zsh
代替。因此,我的解决方案的一些语法必须改变,因为它们以不同方式处理PIPESTATUS
变量。
在bash中,您使用${PIPESTATUS[0]}
,而您将在zsh中使用${pipestatus[1]}
。
第一种方法,使用现有的别名,可能是如下:
makecclip && [ "${pipestatus[1]}" -eq "0" ] && echo "ok"
这将运行仅当"${pipestatus[1]}"
等于0(make的过程中没有错误)
的echo
命令更方便的解决方案是使用函数而不是别名makecclip
。在你~/.bashrc
文件,你可以写:
makecclip() {
make |& tee >(sed "s,\x1B\[[0-9;]*[a-zA-Z],,g" | egrep ":[0-9]+:[0-9]+: error" | cut -d : -f1,2,3 | head -n 1 | xargs -0 echo -n | xclip -selection clipboard && xclip -selection clipboard -o)
return "${pipestatus[1]}"
}
现在,makecclip && echo "ok"
会达到预期效果。
测试用例:
#!/bin/zsh
#do not run this test if there is an existing makefile in your current directory
rm -f makefile
makecclip() {
make |& tee >(sed "s,\x1B\[[0-9;]*[a-zA-Z],,g" | egrep ":[0-9]+:[0-9]+: error" | cut -d : -f1,2,3 | head -n 1 | xargs -0 echo -n | xclip -selection clipboard && xclip -selection clipboard -o)
# this part is only present to check the pipestatus values during the tests.
# In the real function, I wrote 'return ${pipestatus[1]}' instead.
a=(${pipestatus[@]})
echo ${a[@]}
return ${a[1]}
}
echo "# no makefile"
makecclip && echo "ok"
echo -e "\n# empty makefile"
touch makefile
makecclip && echo "ok"
echo -e "\n# dummy makefile entry"
echo -e 'a:\n\[email protected] "inside makefile"' > makefile
makecclip && echo "ok"
echo -e "\n# program with error makefile"
echo -e "int main(){error; return 0;}" > target.cc
echo -e 'a:\n\tgcc target.cc' > makefile
makecclip && echo "ok"
输出:
$ ./test.sh
# no makefile
make: *** No targets specified and no makefile found. Stop.
2 0
# empty makefile
make: *** No targets. Stop.
2 0
# dummy makefile entry
inside makefile
0 0
ok
# program with error
gcc target.cc
target.cc: In function ‘int main()’:
target.cc:1:12: error: ‘error’ was not declared in this scope
int main(){error; return 0;}
^
makefile:2: recipe for target 'a' failed
make: *** [a] Error 1
target.cc:1:12
2 0
我试过,但它似乎并没有工作。我认为这实际上是会改变pipestatus的make,但是我也必须重定向错误。它是否适用于您的测试? –
是的,它在我的电脑上工作得很好。我编辑了我的问题以添加我使用过的测试。 – Aserre
@AdamHunyadi对不起,我花了一段时间才将脚本中的测试用例正式化。你可以看到我运行的测试和输出。 – Aserre