gpt4 book ai didi

shell - 如何以 POSIX 方式实现 'set -o pipefail' - 即将完成,需要专家帮助

转载 作者:IT王子 更新时间:2023-10-29 00:20:32 26 4
gpt4 key购买 nike

我必须以 POSIX 方式实现 BASH set -o pipefail 选项,以便它适用于各种 LINUX/UNIX 风格。稍微解释一下,此选项使用户能够验证所有管道命令是否成功执行。启用此选项后,此命令 cat app.log |如果 cat 失败,则 grep 'ERROR' 失败,否则 cat 错误将被抑制。

所以,我在这里找到了一个非常好的解决方案:http://cfaj.ca/shell/cus-faq-2.html

      run() {
j=1
while eval "\${pipestatus_$j+:} false"; do
unset pipestatus_$j
j=$(($j+1))
done
j=1 com= k=1 l=
for a; do
if [ "x$a" = 'x|' ]; then
com="$com { $l "'3>&-
echo "pipestatus_'$j'=$?" >&3
} 4>&- |'
j=$(($j+1)) l=
else
l="$l \"\$$k\""
fi
k=$(($k+1))
done
com="$com $l"' 3>&- >&4 4>&-
echo "pipestatus_'$j'=$?"'
exec 4>&1
eval "$(exec 3>&1; eval "$com")"
exec 4>&-
j=1
while eval "\${pipestatus_$j+:} false"; do
eval "[ \$pipestatus_$j -eq 0 ]" || return 1
j=$(($j+1))
done
return 0
}

上述run() 函数使用户能够以这种方式调用管道命令:

run cmd1 \| cmd2 \| cmd3

如果其中一个命令失败,您将在 $?

中获取它

但是有一个问题,它不支持管道之间的命令分组。我希望能够调用这样的东西:

run echo "test" ; grep "test" \| awk '{print}'

当我这样做时,调用失败。我无法获得正确的修改来支持命令分组——脚本对于我的 bash 技能来说有点太复杂了……

有人可以帮忙吗?

谢谢!

最佳答案

我的两分钱:

#!/bin/sh

# Saving the pid of the main shell is required,
# as each element of the pipe is a subshell.
self=$$

lots_and_fail() {
seq 100
return 1
}

{ lots_and_fail || kill $self; } | sed s/7/3/

这个东西似乎可以完成这项工作。想法?

关于shell - 如何以 POSIX 方式实现 'set -o pipefail' - 即将完成,需要专家帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13084352/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com