 <p>Your function is not "returning" anything. It prints a value to stdout, and each invocation will do that.</p> <p>If you want to simulate a function return with this mechanism, you need to capture and resend the value:</p> <p>Bash functions return an exit status, and this works as you might expect (as long as you expect 0 to be success). If you don't specify otherwise, the return value is that of the last command. So the following would work:</p> <pre><code>tryn() { if (($1 == 0)); then return 2; fi "$@" || tryn $(($1-1)) "$@" } if tryn 2 ping $host; then # success fi </code></pre>