From b00fe19ef2a0ab83fbe21ea38d04be195faf7924 Mon Sep 17 00:00:00 2001 From: koalaman Date: Tue, 18 Jul 2017 14:40:04 -0700 Subject: [PATCH] Created SC2104 (markdown) --- SC2104.md | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 SC2104.md diff --git a/SC2104.md b/SC2104.md new file mode 100644 index 0000000..6acf0fe --- /dev/null +++ b/SC2104.md @@ -0,0 +1,54 @@ +## In functions, use return instead of break. + +### Problematic code: + +```sh +foo() { + if [[ -z $1 ]] + then + break + fi + echo "Hello $1" +} +``` + +### Correct code: + +```sh +foo() { + if [[ -z $1 ]] + then + return 1 + fi + echo "Hello $1" +} +``` +### Rationale: + +`break` or `continue` are used to abort or continue a loop, and are not the right way to exit a function. Use `return` instead. + +### Exceptions: + +The `break` or `continue` may be intended for a loop that calls the function: + +``` +# Rarely valid +foo() { break; echo $?; } +while true; do foo; done +``` + +This is undefined behavior in POSIX sh. Different shells do different things. + +When the function is called from a loop: + +* `ksh` keeps going and `$?` is 0. +* `bash` version 4.4+ prints an error "break: only meaningful in a \`for', \`while', or \`until' loop", the function keeps going, and `$?` is 0. +* `bash` versions before 4.4, will return from the function, break the loop calling the function, or exit a subshell if there's one in between. +* `dash`, BusyBox `ash`: like above. + +When the function is not called from a loop: + +* All `bash` versions print an error "break: only meaningful in a \`for', \`while', or \`until' loop", the function keeps going, and `$?` is 0. +* `ksh`, `dash` and `ash` silently keep going and `$?` is 0. + +Due to the many different implementations, many of which are not helpful, it's recommended to use proper flow control. A typical solution is making sure the function `return`s success/failure, and calling `myfunction || break` in the loop. \ No newline at end of file