我注意到使用 gradlew
时脚本在 CI 系统中早期成功退出的奇怪问题。 。以下步骤有助于概述这一点。
创建一个名为
script
的文件内容如下:./gradlew echo DONE
获取随机
gradlew
来自某处- 运行
cat script | bash
请注意,DONE 永远不会出现
AFAICT,以非交互方式运行 bash 会导致 exec java blah
在 gradlew
末尾以某种方式允许java关闭stdin并且永远不允许 echo DONE
从通过 stdin 从 cat
读取的脚本中读取。支持这一点的事实是:
- 将脚本更改为
./gradlew; echo DONE
将打印完成 - 替换
./gradlew
与./gradlew < /dev/null
将打印完成
最佳答案
如果您在某处(在您的情况下在 gradlew
内)有一个 exec Something
,您将用以下内容替换当前进程镜像 (bash
)其他东西(java
)。
来自帮助执行
:
exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
Replace the shell with the given command.
所以问题不在于 stdin 被关闭,发生的事情是新进程 (java
) 将是读取该输入的进程 ( “echo DONE”),并且可能不执行任何操作。
举例说明
考虑这个 script.sh:
#!/bin/bash
echo Hello
exec cat
echo World
如果您执行它,为 cat
提供一些输入:
$ ./script.sh <<< "Nice"
Hello
Nice
您可能还期望屏幕上打印出世界一词...错误!
这里没有任何反应,因为在 exec
命令之后执行了其他任何操作。
现在,如果您将脚本通过管道传输到 bash:
$ cat script.sh | bash
Hello <- bash interpreted "echo Hello" and printed Hello
echo World <- cat read "echo World" and printed it (no interpertation ocurred)
在这里您可以清楚地看到正在执行的流程图像替换。
关于linux - 为什么在非交互式 bash session 中运行 gradlew 会关闭 session 的标准输入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50147013/