[SOLVED] function that tests variable and sets default value
Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I understand everything you have written and fully understand how local works. I could follow your demo example. Internally demo sets var as a completely different variable than the global one. The global one is not affected by the status of the local one.
I want to make this point though. Let us assume that I will be passing a variable to demo (either a global one or a local one defined in some other function), which I would like to change for use elsewhere (e.g. to call another function). My school of thought is that in such situations, the use of
Code:
local -n var="$1"
is superfluous, and one can actually use
Code:
typeset -n var="$1" ; var=something_else
The typeset expression works in the same way as changing the variable passed as $1 to be set to a new value something_else, with something_else being seen outside the function. Using local or typeset does not make any actual difference in the result.
If I'm gonna do something like that, then the first line of my script is gonna look something like this:
Code:
#!/usr/bin/perl
(Pick the language processor of your choice to put in the so-called "shebang" line.) And then, I'm gonna write the rest of the script in a real programming language. No one will ever know. The shell will silently invoke the stated language processor, hand the rest of the script to it, and off you go.
The only shell that was ever intended to embed a "real" programming language was Dr. Korn's ksh, which I have seen "in the field" only one time. Bash's scripting capabilities, such as they are, are very primitive. And so, I simply don't bother to do much with it. Thanks to the very elegant mechanism of "shebang," it simply isn't necessary.
I agree completely. The archaic nature of bash especially the necessity of specifying local declarations inside the function, rather than automatically defining all variables in functions with local context, makes everything much long-winded and frustrating.
Still, for things that I have in bash, I do try to follow good procedures nevertheless.
Even in perl you should declare a variable with the my keyword.
But then it is automatic. my means "as local as possible". (Local to the current module in the main code, local to the function in a function.)
The link only explains what local in a function is.
Does not explain what happens if you'd use typeset or declare in a function.
Also the man page is unclear.
Variables local to the function may be declared with the local builtin (local variables).
Nothing else mentioned.
But in the next paragraph:
Quote:
Consequently, a local variable at the current local scope is a variable declared using the local or declare builtins in the function that is currently executing.
And it is documented that declare and typeset are synonyms.
My conclusion is:
use local in a function, otherwise you walk on unsafe ground.
Last edited by MadeInGermany; 05-03-2023 at 11:09 AM.
Also the man page is unclear.
...
My conclusion is:
use local in a function, otherwise you walk on poorly documented ground.
The manual is not unclear.
If you want to know what a built-in command does, go to the Index, select the relevant section (i.e. Index of Shell Builtin Commands) and select the name of the command, i.e. declare or typeset, then read the text provided...
Quote:
Originally Posted by https://www.gnu.org/software/bash/manual/html_node/Bash-Builtins.html#index-declare
declare
...
The -g option forces variables to be created or modified at the global scope, even when declare is executed in a shell function.
...
When used in a function, declare makes each name local, as with the local command, unless the -g option is used.
Quote:
Originally Posted by https://www.gnu.org/software/bash/manual/html_node/Bash-Builtins.html#index-typeset
typeset
typeset [-afFgrxilnrtux] [-p] [name[=value] …]
The typeset command is supplied for compatibility with the Korn shell. It is a synonym for the declare builtin command.
My suggestion was driven by your comment about walking on unsafe ground. Might there be need for more explanation for users to be able to decide what to use in given circumstances more clearly?
My focus has mainly been about using
Code:
typeset -n var="$1"
if you know that the variable defined for $1 will be change by the function. Otherwise I would always use local.
Strictly speaking
Code:
local -n var="$1"
ensures var is a local variable, but setting var to something else would change the value of the variable referenced by $1.
But the subsequent discussion mainly focused on just the local declaration, rather than the necessity of having a nameref variable via -n.
I do not know if it is just me, but -n seems to change the fundamental purpose of local because the capabilities of a reference variable goes further than the strict sense of the local declarion using just
But using the nameref option -n effectively changes the meaning of "local" to allow the variable to be modified and retain its value outside of the function. Thus, making the variable "global" within the script.
If I may be utterly frank, to me, things like typeset are basically "putting lipstick on a pig." These are "things that have been 'subsequently invented'" to try to press "bash scripting" into service, when "bash, itself" wisely offered #!shebang" as a much more elegant and simple solution to the underlying problem.
Frankly, it becomes tiring to walk into yet another situation that is "held together by bubblegum and Scotch® tape." The system "sort-of" works, but now it has to be changed and no one is confident to do it. Because it's a baffling amount of "shell scripting," and the guy (RIP ...) who just got hit by a bread truck is no longer here to maintain it.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.