Developing Linux Shell Scripts is just not the same as programming in modern programming language. At least to me, it still feels novel and at times a bit weird. I am currently engaged in some scripting that requires the use of functions. That is all well, but I want to pass input parameters into my functions (instead of relying on global variables) and I would like to be able to receive the result from a function instead of – again- working through global variables. Readability, encapsulation, refactorability and reuse are just some of the reasons why I want to have this.
Although not completely intuitive, I can get what I want to a large degree. See how:
https://gist.github.com/lucasjellema/b2f54d2f427a9dc1767970f2ee472e5b
The function receives input parameters or arguments through $1 for the first argument, $2 for the second and so on. There is not formal declaration of input parameters in the function header. Here we need to rely on discipline and describe the expected input in lines of comment. (and apply the best practice proposed by Frits Hoogland to immediately copy all arguments to local variables)
The function does not have something akin to a return statement. However, we can agree on a handshake with our invokers that boils down to: anything produced by this function (produced as in echo-ed) can be considered part of the result returned by the function. The caller can simply evaluate the function call into a variable and consider that the formal result from the function. In this example, we see how variable WELCOME_MESSAGE is initialized with the expression $(function call). This means that anything echo-ed inside the function ends up in the variable. The $() notation results in whatever is passed into it to be evaluated. Note that ${} can be nested. (the backtick notation can also be used – as Frits indicates it is less current and can not be nested)
Single Quotes, Double Quotes, Evaluation of Expressions
When programming shell script, it is important to work correctly with quotes and double quotes, as my colleague Henk Jan pointed out to me.
- When a string is enclosed in single quotes – it is taken literally. No expansion of variables takes place. ‘$VARIABLE’ will stay just that – $VARIABLE
- When a string is enclosed in double quotes, variables are expanded with their value and single quotes can be embedded. “$VARIABLE” will be converted to – <Value of VARIABLE>
- When a string is enclosed in $() (or in back ticks), it is evaluated as an expression.
- When a string contains an arithmetical expression, it can be executed with $(($VARIABLE)) ;
VAR1=”JOHN”
VAR2=”45″
echo $(echo “$VAR1 reached the age of $VAR2”)
// prints JOHN reached the age of 45
VAR2=”45″
VAR3=”$VAR2+$VAR2″
echo $(($VAR3)) // prints 90
echo $(($VAR2+$VAR2)) // prints 90
See Shell Parameter Expansion: https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html
Note:
- $’…’ performs character escapes like \n, but doesn’t expand variables.
- $”…” is for human-language translations in Bash and ksh.
See for example: https://unix.stackexchange.com/questions/503013/what-is-the-difference-between-and-quotes
Resources
I found half of the answer in this article: https://www.linuxjournal.com/content/return-values-bash-functions
In modern bash versions (I don’t know which version qualifies as modern, but it has been there for a long time), it’s better to use $( .. ) than ` .. ` for inline execution. The latter (“backticks”) can not be nested, whilst $( .. ) can.
It’s also good practice to assign parameters to named variables at the start of a function, to make sure the parameter variables are not re-assigned (and that follows the practice of what most of us have learned, to declare the variables at the start). So:
my_function()
{
TO_VAR=$1
FROM_VAR=$2
… rest of function …
}
Of course the assignment to WELCOME_MESSAGE is not necessary, but I guess you wanted to show how to assign the output of calling a function to a variable.
Hi Frits,
Thanks for your clear comments. I will edit the gist and the article accordingly. I am really not well versed in Shell Scripting – as I have clearly demonstrated and you have just as clearly pointed out.
regards,
Lucas