如果子shell返回错误,则中止heredoc命令?

时间:2019-08-09 16:10:07

标签: bash heredoc

set -u
cat <<EOF
$FOO
bar
EOF

打印:-bash: FOO: unbound variable并返回1。这就是我想要的。 但是这个:

set -u
foo() { echo $FOO; }
cat <<EOF
$(foo)
bar
EOF

打印:

-bash: FOO: unbound variable

bar

并返回0。

我正在寻找一种使后者的片段表现与前者相同的好方法。 有什么想法吗?

更新 我认为,从到目前为止的答案中,我需要澄清一下用例,因为上面的示例有点简化。

我所追求的是一种原始的“模板处理”。 有一个通用模板,其中包含一些“可配置的部分”,例如:

cat user.json
{
    "id": "$USER_ID",
    "name": "$USER_NAME",
    "roles": "$(ROLES director)", 
}

然后有一些输入:

cat peter.sh
USER_ID=foo
USER_NAME=peter
ROLES() { cat ${1}_roles.text | grep $USER_ID }

然后“模板处理器”执行以下操作:

. peter.sh
set -u
contents="$(<user.json)"
eval "cat <<EOF
$contents
EOF
"

都是变量和函数都在处理器外部,它不知道它们是什么,所以 (1)我无法在实际执行Heredoc之前评估所有函数,因为我不知道它们是什么(以及如何使用它们),并且 (2)我不能做@suspectus建议的$(foo) && bar || $FOO_UNKNOWN之类的事情,因为bar必须是模板的其余部分。

还有其他想法吗?

2 个答案:

答案 0 :(得分:1)

它的行为必须完全相同吗?只是一个额外的错误输出-:

set -u
foo() { $FOO; }
cat <<EOF
$(foo) && bar || $FOO_UNKNOWN
EOF

答案 1 :(得分:1)

可能的解决方法可以是在here-doc之前调用函数,如果存在未绑定的变量,则让其退出:

foo() { echo "$FOO"; }

set -u
var="$(foo)" || exit 1
cat <<-EOF
$var
bar
EOF

输出:

FOO: unbound variable

退出状态为1