I've noticed this strange issue of scripts exiting successfully early in a CI system when using gradlew
. The following steps help outline this.
Create a file called script
with the contents:
./gradlew
echo DONE
Get a random gradlew
from somewhere
cat script | bash
Notice that DONE never appears
AFAICT, running bash non-interactively causes the exec java blah
at the end of gradlew
to somehow allow java to close stdin and never allow the echo DONE
to be read from the script being read in via stdin from cat
. Supporting facts of this are:
./gradlew; echo DONE
will print DONE./gradlew
with ./gradlew < /dev/null
will print DONEIf you have an exec something
somewhere (within gradlew
in your case), you are replacing the current process image (bash
) with something else (java
).
From help exec
:
exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
Replace the shell with the given command.
So the problem is not that stdin is getting closed, what is happening is that the new process (java
) will be the one reading that input ("echo DONE") and probably doing nothing with it.
Consider this script.sh:
#!/bin/bash
echo Hello
exec cat
echo World
If you execute it providing some input for cat
:
$ ./script.sh <<< "Nice"
Hello
Nice
You may expect also the word World be printed on the screen... WRONG!
Here nothing happens because anything else is executed after the exec
command.
Now, if you pipe the script to 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)
Here you can clearly see the process image replacement in action.