[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Preventing Bash Variable Confusion

From: Roger
Subject: Re: Preventing Bash Variable Confusion
Date: Wed, 29 Jan 2020 14:05:53 -0500
User-agent: Mutt/1.10.1 (2018-07-13)

> On Thu, Jan 30, 2020 at 01:03:31AM +0700, Robert Elz wrote:
>    Date:        Wed, 29 Jan 2020 09:23:05 -0500
>    From:        Greg Wooledge <address@hidden>
>    Message-ID:  <address@hidden>
>  | As far as functions go, bash allows you to define local variables within
>  | a function.  This avoids namespace collisions as long as you're within
>  | that function.
>It actually doesn't, or not generally - it allows the function to avoid
>namespace collisions with random globals (or other locals) that might exist
>up the call stack, but doesn't prevent functions that are called from
>trampling all over this function's local vars.
>Some variants of ksh apparently make local vars work more like local
>vars in C (or other similar languages) and inaccessible outside the
>function, but that doesn't really work well for shell, it is useful
>to be able to make things like PATH, IFS, ... local in a function,
>change their values, and then call other functions which then use
>(and can alter) the modified values.
>  | Obviously, sh doesn't have this feature,
>The POSIX spec doesn't have local vars, but all the shells that are
>used very much do, though the details of exactly how they work differ.
>If we could get everyone to agree on how they should work, they'd be
>in POSIX by now as well.
>  | Since the Subject: of this thread includes the word "Bash", it seems
>  | likely that the OP is not concerned with portable-sh issues at the
>  | moment.
>Of course, which is why I suggested using local vars.   One must however
>remain aware of the limitations.  Of course if the function in question
>calls no other functions, then there is no problem, but knowing that is
>true for any function that does any more than variable manipulations
>(X=${Y%...} type things, including arithmetic, and which doesn't do everything
>in a subshell) is very difficult, and then unless the function writes
>"command" (or in bash, perhaps "builtin") before everything that is a
>command, then it remains vulnerable.
>Consider the proposed trap handling function, copied from another message
>       sigint_handler() {
>               trap - INT
>               kill -INT $$
>       }
>(which has no vars, and manipulates none, so looks dafe enough) but
>then consider
>       trap() {
>               My_Var=123
>               command trap "$@"
>       }
>       kill() {
>               PATH=/bin:/usr/bin
>               command kill "$@"
>       }
>and to make this a little more illustrative, consider that instead
>of the above, we have:
>       sigint_handler() {
>               local My_Var=$$
>               trap - INT
>               kill -s INT "${My_Var}"
>       }
>None of this is very likely in practice, but things like it do
>occasionally happen.
>It could be fixed by
>       sigint_handler() {
>               command local My_Var=$$
>               command trap - INT
>               command kill -s INT "${My_Var}"
>       }
>but when you find someone who actually writes their code like that,
>please let me know.

Bash's built-in command is referenced within the following books.

Newham, C. (2005). "Learning the Bash Shell 3rd ed. O'Reilly Media.
Chapter 7, Input/Output and Command-Line Processing, "Command-Line Processing", 

Burtch, K. (2004). Linux Shell Scripting with Bash. Sams.
Chapter 14, Functions and Shells, "Recursion and Nested Functions", p264

I've seen command used, but usually within some very hefty larger or corporate 
related scripts.  "command local", likely far fewer.

"Linux Shell Scripting with Bash." (Burtch) suggested using declare instead of 
local, due to local lacking the other switches declare provides. p262 (eg.  
declare can specify type of variable, such as integar only.)

Between these two books, I prefer Burtch'ss book for strongly condoning 
readable and writing good fall back code. (Fallback code gets quite lengthy 
though.) Cameron's book is loaded with information.  Both are good reads.

So in a nutshell, likely best to use "declare" within functions, although local 
is quicker and explicitly read as local.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]