The question is published on by Tutorial Guruji team.
I’m been having some weird problems with bash lately. While trying to simplify my script, I came up with this small piece of code:
$ o(){ echo | while read -r; do return 0; done; echo $?;}; o 0 $ o(){ echo | while read -r; do return 1; done; echo $?;}; o 1
return
should have exited the function without printing $?
, shouldn’t it? Well, then I checked if I can return from a pipe alone:
$ echo | while read -r; do return 1; done bash: return: can only `return' from a function or sourced script
The same happens without a while
loop:
$ foo(){ : | return 1; echo "This should not be printed.";} $ foo This should not be printed.
Is there something I’m missing here? A Google search brought nothing about this! My bash version is 4.2.37(1)-release on Debian Wheezy.
Answer
Related: https://stackoverflow.com/a/7804208/4937930
It’s not a bug that you cannot exit a script or return from a function by exit
or return
in subshells. They are executed in another process and not affecting the main process.
Besides that, I suppose you are seeing undocumented behaviors of bash on (probably) undefined spec. In a function, no errors are asserted for return
at top level of subshell commands and it just behaves like exit
.
IMHO it’s a bash bug for the inconsistent behavior of return
depending on whether the main statement is in a function or not.
#!/bin/bash o() { # Runtime error, but no errors are asserted, # each $? is set to the return code. echo | return 10 echo $? (return 11) echo $? # Valid, each $? is set to the exit code. echo | exit 12 echo $? (exit 13) echo $? } o # Runtime errors are asserted, each $? is set to 1. echo | return 20 echo $? (return 21) echo $? # Valid, each $? is set to the exit code. echo | exit 22 echo $? (exit 23) echo $?
Output:
$ bash script.sh 10 11 12 13 script.sh: line 20: return: can only `return' from a function or sourced script 1 script.sh: line 22: return: can only `return' from a function or sourced script 1 22 23