当某些内容写入 stderr 时停止执行

当某些内容写入 stderr 时停止执行

我在 bash 脚本中处理错误时遇到问题。到目前为止,我在 bash 中看到的错误处理解决方案似乎都不适用于此示例脚本:

#!/usr/bin/env bash
set -euo pipefail

eval $(do_stuff)
touch file

输出是:

./script.sh: line 4: do_stuff: command not found

但即便如此,它仍然愉快地继续并创建文件,这正是我想要禁止的。我想我可以将 stderr 通过管道传输到另一个程序,并在它获取一些输出时终止整个程序:

unbuffer ./script.sh 2>&1|{ while read stdin; do echo $stdin;killall -9 bash;done; }

然而,它大约只有 5% 的时间有效。在大多数情况下,它无法尽早终止脚本。

答案1

我想出了如何优雅地处理我发布的案例:

eval() {
    if [[ -z "${@}" ]];then
        exit 1
    fi
    builtin eval "$@"
}

它会覆盖默认的 eval() 实现,如果没有收到输入,则会退出。但我不会接受这个答案,因为它仍然没有回答这个问题的标题。

答案2

只需先将其更改为赋值,然后再评估即可。

示例1(输入命令无效则停止):

[xiaobai@localhost ~]$ cat h2.sh
#!/bin/bash

trap err_handler ERR
err_handler() { echo trapped ; exit; }
e2=$(echoasasas)
eval "$e2"
echo "next"
[xiaobai@localhost ~]$ sh h2.sh
h2.sh: line 5: echoasasas: command not found
trapped
[xiaobai@localhost ~]$ 

示例 2(如果输出不是有效命令则停止):

[xiaobai@localhost ~]$ cat h2.sh
#!/bin/bash

trap err_handler ERR
err_handler() { echo trapped ; exit; }
e2=$(echo xxxxx)
eval "$e2"
echo "next"
[xiaobai@localhost ~]$ sh h2.sh
h2.sh: line 6: xxxxx: command not found
trapped
[xiaobai@localhost ~]$ 

示例 3(继续运行下一个命令):

[xiaobai@localhost ~]$ cat h2.sh
#!/bin/bash

trap err_handler ERR
err_handler() { echo trapped ; exit; }
e2=$(echo ls)
eval "$e2"
echo "next"
[xiaobai@localhost ~]$ sh h2.sh
Android  CRITICAL  Documents
next
[xiaobai@localhost ~]$ 

示例 4(如果 STDERR 在另一个 shell 中触发,则一半):

[xiaobai@localhost ~]$ cat /tmp/so.sh 
ls yyyyyy 2>/tmp/kas
[xiaobai@localhost ~]$ cat /tmp/kas
[xiaobai@localhost ~]$ cat h2.sh
#!/bin/bash

trap err_handler ERR
err_handler() { echo trapped ; exit; }
echo "before"
e2=$(/bin/bash /tmp/so.sh)
eval "$e2"
echo "next"
[xiaobai@localhost ~]$ sh h2.sh
before
trapped
[xiaobai@localhost ~]$ cat /tmp/kas
ls: cannot access 'yyyyyy': No such file or directory
[xiaobai@localhost ~]$ 

相关内容