Shell 脚本流程被 gradle 任务中断

问题描述 投票:0回答:1

考虑以下 shell 脚本:

#!/bin/bash

echo Hello
gradle clean
echo Bye

通过文件运行时,预期输出是正确的。

$ chmod +x script.sh
$ ./script.sh

Hello
BUILD SUCCESSFUL in 1s
1 actionable task: 1 up-to-date
Bye

当通过 stdin 运行时,预期输出是错误的。

$ cat script.sh | bash -s

Hello
BUILD SUCCESSFUL in 1s
1 actionable task: 1 up-to-date

在 stdin 情况下,运行

gradle clean
后,脚本流程被中断,以返回码 0 退出,并且永远不会到达下一个命令。我正在搜索通过 stdin 执行上述脚本的方法,因为我将使用带curl的管道,例如
curl -so- http://host/script.sh | bash -s

我可以解决它在新管道中包裹

gradle
的问题,但我也不明白它为什么起作用:

#!/bin/bash

echo Hello
echo gradle clean | bash -s
echo Bye

我想找到一个简洁的解决方案(例如:bash/gradle 中的标志)。谢谢。

android bash shell gradle
1个回答
0
投票

正如戈登·戴维森

所指出的

gradle
大概是从标准输入读取,因此它读取脚本的其余部分,而不是让 shell 读取并执行它。如果
gradle
实际上不需要任何输入,请尝试使用
gradle clean </dev/null

您可以使用

重现类似的错误
bash -s << 'EOF'
read var
echo "this line is consumed by read"
echo "end of script"
EOF

我不想窃取戈登·戴维森的答案。如果他们写了答案,请接受他们的答案。不过,我有一些重要的事情要补充:

当您计划使用

curl | bash -s
执行脚本时,最好针对此错误和其他典型错误添加更一般的预防措施。
如果您的目标系统支持进程替换,那么您可以将脚本包装在

bash <(cat <<'END_OF_SCRIPT'
insert your
entire script
here
END_OF_SCRIPT
)

这至少可以防止以下问题

  • 来自脚本的命令可能会消耗来自标准输入的脚本(你的问题)
  • curl
    下载脚本的前半部分,但随后失败。脚本只执行了一半。在这种情况下,用户不会收到错误消息(
    curl -s
    silent,并且bash不知道应该遵循更多命令,除非您处于命令块的中间,例如
    if ...; then
    )也没有退出代码(
    curl
    可能会以非零值退出;但该代码在管道中丢失
    curl | bash
    )。

bash -e
和/或
set -e
等出现问题时,您可能还想使用
mkdir somedir
/
cd somedir
来停止脚本。有一些警告,但总比没有好。

© www.soinside.com 2019 - 2024. All rights reserved.