0

I'm new to bash. I'm confused about the way functions work in this language.

I have written this code:

#!/usr/bin/env sh

choice_func() {
        echo "$choice"
}

echo "Enter your choice:"
read choice
choice_func

While investigating my code, I realized that I have forgotten to send the value of choice as input when calling choice_func(). But it works properly! how it is possible that the function has not been given the input but can echo it?

Kusalananda
  • 320,670
  • 36
  • 633
  • 936
Pablo
  • 177
  • 7
  • 2
    "choice" is a global value. It is not defined when choice_func is defined, nor as an argument, but it is in scope before the function is called. – Paul_Pedant Apr 09 '20 at 14:27
  • For gory details, see [List of shells that support `local` keyword for defining local variables](https://unix.stackexchange.com/questions/493729/list-of-shells-that-support-local-keyword-for-defining-local-variables) – steeldriver Apr 09 '20 at 14:34

2 Answers2

3

You read a value into the variable choice in the main part of the script. This variable has global scope (for want of a better word), which means that it will be visible inside the function too.

Note that if you were to read the value inside the function, then the variable would still have global scope and be visible outside the function (after the function call). This would be the case unless you declared it as local with local choice inside the function.

For more information about scoping of shell variable, see e.g.

To pass the value in the variable choice to the function, use

choice_func "$choice"

The function can then access this value in $1, its first positional parameter:

choice_func () {
    echo "$1"
}

or

choice_func () {
   local choice="$1"

   # choice is now local and separate from the variable
   # with the same name in the main script.

   echo "$choice"
}

This is the proper way to pass a value to a function without relying on global variables in a shell script.

Kusalananda
  • 320,670
  • 36
  • 633
  • 936
  • So calling function like `choice_func "$choice"` is useless? – Pablo Apr 09 '20 at 14:36
  • @Pablo No, calling `choice_func "$choice"` (note the `$`) gives the function its value in the first positional parameter, `$1`. It would be a good thing to do. I will add this to the answer. – Kusalananda Apr 09 '20 at 14:38
  • Thanks, I understood it now. By the way, here in the function `local choice` will create a local variable whose value will not change or influence the value of global `choice`, right? – Pablo Apr 09 '20 at 14:43
  • @Pablo Correct. – Kusalananda Apr 09 '20 at 14:50
0

Because you have designed your function with no need of an argument, that's all.

Paulo Tomé
  • 3,754
  • 6
  • 26
  • 38
John Goofy
  • 911
  • 1
  • 6
  • 17
  • What do you mean with no need of an argument? It `echo` the value of $choice, it will also create directories based on the value of `choice` later in my function. – Pablo Apr 09 '20 at 14:33
  • Please type `info bash` than `i` than `function` an read the paragraph with positional parameters, knowen in other languages as arguments to an function. – John Goofy Apr 09 '20 at 14:39