-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Idea: Encourage more local variables #1954
Comments
I strongly vote for this. I suggest that global scope variables could be recognized by upper case characters Any other variable in functions should be assumed to be local. Many thanks. Really cool code checker! |
Upper case variables indicate that the scope is environment global, they are set outside the script. Not sure if I have invented this myself or inherited from somewhere. |
I think that this could be a good rule: suggest the usage of |
I must say I was surprised that shellcheck doesn't already do this. Were there any attempts at implementing it? |
This is not only problem of explicit assignments. For example this... #!/usr/bin/bash
f()
{
for i in hello
do
echo $i
done
}
f
echo $i will print "hello" twice. $ ./hello
hello
hello |
There is the additional problem that 'local' is not part of POSIX and some shells refuse to implement it. Consequently, scoping your variables is non-portable. It is nice thing to have for shells that implement it but probably should not be the default. |
shellcheck is already capable of distinguishing the shell implementation, by reading the shebang, thus emitting specific warnings. |
I think that
Not only because of Consider the following: x=7
function foo { echo "in foo: $x"; }
function bar { typeset x=42; foo; }
bar
foo It prints...
... in bash, but in ksh93, it prints...
... because of static scoping. Now consider, the same program, but the other style of function definition... x=7
foo() { echo "in foo: $x"; }
bar() { typeset x=42; foo; }
bar
foo The bash gives the same output, but
... because typeset is ignored. I'm not sure how other ksh implementations behave and I do realize, it's a minefield, but that deoesn't detract from potential usefulness of some form of warning. My only regret is that my haskell is extremely rusty after some 19 years, so I'm unlikely to contribute myself to this. |
For new checks and feature suggestions
Here's a snippet or screenshot that shows the problem:
Here's what shellcheck currently says:
(nothing)
Here's what I wanted or expected to see:
We noticed that you appear to be using a modern bash descendant shell with an unexported, non-command-prefix, function lifetime variable assignment in lowercase outside of the conventional bindings
http_proxy
,HTTP_PROXY
,https_proxy
,HTTPS_PROXY
,IFS
,PATH
,LIBS
,CC
,USER
,HOME
,BASH_VERSION
, etc. etc. and would think it prudent to mark this variablelocal
to reduce the risk of collision with variables in other scripts. If, on the other hand, the variable is intended for to be sourced into other scripts, note that convention is UPPER_SNAKE_CASE with an accompanyingexport
statement.Notes
I realize it's late in the game to attempt such a feat, but I think it's still practically doable. The lack of an
export
, lack of a reference to the same variable above or below the function declaration, and casing all point to the intent for the variable to be function scoped. ShellCheck could help notify the programmer that such a variable actually leaks into the rest of the script without alocal
designator.The number of false positives is something to consider. A modest whitelist of common exceptions
http_proxy
,https_proxy
, and so on could reduce the need for the programmer to create exceptions to the rule. Hopefully we can leverage casing for most of this.Some kind of naming convention for not-exported-but-not-function-lifetimed variables could further help the programmer and the linter to establish variable scope more clearly.
The text was updated successfully, but these errors were encountered: