The sh(1) man page says: "Variables may be declared to be local to a function by using the local command. This should appear as the first statement of a function, and the syntax is: ..." The part that I personally feel confused about is: "This should appear as the first statement of a function" - it seems that in practice this is not the case. I created a test shell script to check this out: ----------------------------------------------------- #!/bin/sh a="Val 1" foo() { a="Val 3" echo "foo(): a before: ${a}" local a="Val 2" echo "foo(): a after: ${a}" } echo "a before: ${a}" foo echo "a after: ${a}" ----------------------------------------------------- Here I intentionally made 'local' line not the first function statement, but from the output of the script I can draw that the 'local' keyword still works as it should, i.e. keeps a variable local to the function. Output of the script follows: ----------------------------------------------------- a before: Val 1 foo(): a before: Val 3 foo(): a after: Val 2 a after: Val 3 ----------------------------------------------------- Please, let me know whether it is a bug in the manual page (the implementation behaviour is correct, but the documentation is not), or it is a bug in the implementation (the 'local' shouldn't work if it's not a first function statement), or it is me who interpreted things the wrong way.
This is indeed a bug in the manual page; a `local` statement may appear anywhere inside a function (but only inside a function).
https://reviews.freebsd.org/D57596
A commit in branch main references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=556e793d803e12e9ad9361c6c53ed0433151f41e commit 556e793d803e12e9ad9361c6c53ed0433151f41e Author: Dag-Erling Smørgrav <des@FreeBSD.org> AuthorDate: 2026-06-16 20:23:18 +0000 Commit: Dag-Erling Smørgrav <des@FreeBSD.org> CommitDate: 2026-06-16 20:23:18 +0000 sh: Improve function documentation * Mention that the function body can be in parentheses. It is already implied since the function body can be any valid statement, but it may not be obvious to a reader who has only ever seen functions that used curly brackets and assumes that they are part of the function syntax. * Remove the incorrect claim that a local statement may only occur at the top of a function. * Show that a value may be assigned to a variable in a local statement. * While here, replace unpaired double quotes with \(dq to avoid confusing syntax highlighters. PR: 296050 MFC after: 1 week Reviewed by: ziaee, jilles Differential Revision: https://reviews.freebsd.org/D57596 bin/sh/sh.1 | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-)
A commit in branch stable/15 references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=ea13334abd9f4ed5456ba58970ee426a48c9c8e6 commit ea13334abd9f4ed5456ba58970ee426a48c9c8e6 Author: Dag-Erling Smørgrav <des@FreeBSD.org> AuthorDate: 2026-06-16 20:23:18 +0000 Commit: Dag-Erling Smørgrav <des@FreeBSD.org> CommitDate: 2026-06-20 19:02:47 +0000 sh: Improve function documentation * Mention that the function body can be in parentheses. It is already implied since the function body can be any valid statement, but it may not be obvious to a reader who has only ever seen functions that used curly brackets and assumes that they are part of the function syntax. * Remove the incorrect claim that a local statement may only occur at the top of a function. * Show that a value may be assigned to a variable in a local statement. * While here, replace unpaired double quotes with \(dq to avoid confusing syntax highlighters. PR: 296050 MFC after: 1 week Reviewed by: ziaee, jilles Differential Revision: https://reviews.freebsd.org/D57596 (cherry picked from commit 556e793d803e12e9ad9361c6c53ed0433151f41e) sh: Belatedly bump manual page date Fixes: 556e793d803e ("sh: Improve function documentation") (cherry picked from commit 09bb0b0d13968163c7394e9168491b16607fc2e7) bin/sh/sh.1 | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-)
A commit in branch stable/14 references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=cee36a5e003c90659f274a2f20699543c73f2d34 commit cee36a5e003c90659f274a2f20699543c73f2d34 Author: Dag-Erling Smørgrav <des@FreeBSD.org> AuthorDate: 2026-06-16 20:23:18 +0000 Commit: Dag-Erling Smørgrav <des@FreeBSD.org> CommitDate: 2026-06-20 19:02:53 +0000 sh: Improve function documentation * Mention that the function body can be in parentheses. It is already implied since the function body can be any valid statement, but it may not be obvious to a reader who has only ever seen functions that used curly brackets and assumes that they are part of the function syntax. * Remove the incorrect claim that a local statement may only occur at the top of a function. * Show that a value may be assigned to a variable in a local statement. * While here, replace unpaired double quotes with \(dq to avoid confusing syntax highlighters. PR: 296050 MFC after: 1 week Reviewed by: ziaee, jilles Differential Revision: https://reviews.freebsd.org/D57596 (cherry picked from commit 556e793d803e12e9ad9361c6c53ed0433151f41e) sh: Belatedly bump manual page date Fixes: 556e793d803e ("sh: Improve function documentation") (cherry picked from commit 09bb0b0d13968163c7394e9168491b16607fc2e7) bin/sh/sh.1 | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-)