$ for i in $(seq 1 100); do ./bad.sh | grep 'got lock'; done | sort | uniq -c 100 Process 1 got lock 100 Process 2 got lock 100 Process 3 got lock $ for i in $(seq 1 100); do ./good.sh | grep 'got lock'; done | sort | uniq -c 80 Process 1 got lock 17 Process 2 got lock 3 Process 3 got lock $ $ ./example.sh & ./example.sh & [1] 15157 [2] 15158 $ 15157 locking 15158 locking 15157 got lock, working... 15158 locking 15158 locking 15157 unlocking 15158 locking 15158 got lock, working... 15158 unlocking [1]- Done ./example.sh [2]+ Done ./example.sh $ $ ./example.sh 15202 locking 15202 got lock, working... ^C $ ./example.sh 15205 locking 15205 locking 15205 locking 15205 locking 15205 locking 15205 failed $