非交互式Bash会话中运行gradlew关闭stdin致脚本提前退出的原因?
Hey folks, I recently ran into a tricky issue when using gradlew in CI systems: the script exits prematurely, and subsequent commands never get executed. Let me walk you through how to reproduce this and why it happens:
Reproduction Steps
- Create a file named
scriptwith this content:./gradlew echo DONE - Grab any valid
gradlewscript (you can copy one from any Gradle project) - Run the command:
cat script | bash - You’ll notice that the string
DONEnever gets printed—even though it’s right there in the script.
Root Cause Analysis
After digging into it, I found the issue occurs specifically when running Bash in non-interactive mode. The gradlew script ends with an exec java ... command, which replaces the current shell process with the Java process. When Java exits, it closes the standard input (stdin) stream. Since we’re feeding the script to Bash via cat script | bash, once stdin is closed, Bash stops reading the rest of the script—so the echo DONE line never even gets processed.
Workarounds
To fix this, we need to prevent gradlew from messing with the script’s stdin. Here are two simple ways:
- Redirect stdin for gradlew:
This disconnects./gradlew echo DONE < /dev/nullgradlewfrom the script’s stdin, so Java won’t close it when it exits. - Run gradlew in a subshell:
The subshell has its own stdin, so closing it won’t affect the parent shell reading the rest of the script.(./gradlew echo DONE)
After making either change, running cat script | bash will correctly output DONE as expected.
内容的提问来源于stack exchange,提问作者edaniels

