修改zsh命令以转发错误

修改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 
+0

我试过,但它似乎并没有工作。我认为这实际上是会改变pipestatus的make,但是我也必须重定向错误。它是否适用于您的测试? –

+0

是的,它在我的电脑上工作得很好。我编辑了我的问题以添加我使用过的测试。 – Aserre

+0

@AdamHunyadi对不起,我花了一段时间才将脚本中的测试用例正式化。你可以看到我运行的测试和输出。 – Aserre