4

lets say I have a script called hello

$ cat hello
function1 () {
echo $1
}
function1 what
echo $1

and I call

$ sh hello chicken
what
chicken

How do i refer to the script parameters (chicken) inside the function. Would I have to rename all the script arguments or store them somewhere else? Whats the best way to handle this?

3
  • 6
    Pass the parameters you need to the function (function1 what $1). It's kind of like scoping in a traditional programming language. Commented Jun 10, 2021 at 23:29
  • 8
    Script arguments are not (directly) available inside functions; if you want them to be available, you need to either assign them to (global) variables, or pass them on as arguments to the functions. (Passing them on is usually the cleaner option.) Commented Jun 11, 2021 at 0:14
  • Bash, or sh? Different answers between them -- in bash you can copy global arguments into an array and reference it from elsewhere; sh has no such capability. Commented Apr 13, 2024 at 20:00

2 Answers 2

0

This is a case of shadowing, you can find information about it below https://www.gnu.org/software/bash/manual/html_node/Shell-Functions.html

If you try to picture it, the inner scope variable casts a "shadow" over the outer scope variable and hides it from view. As soon as the inner scope variable is gone, the program can again "find" the outer scope variable.

It's pretty much another variation of a general rule in programming where things that are more specific or refer to an inner scope, override things that are more generic or part of an outer scope.

If you wrote

temp="hi"
phrase(){
    echo "$temp"
    temp="hello"
    echo "$temp"
}
phrase

The result would be

hi
hello

because the variable of the inner scope "overshadows" the variable of the outer scope.

That can be prevented by storing your script's $1 parameter using another name. So, as you said, the best approach is to make sure all variables have different names by storing your script parameters inside distinctly named variables.

temp=$1
function1 () {
  echo "$1"
  echo "$temp"
}
function1 what
echo "$1"

Edit: I forgot to account for the fact that script variables are not available directly inside functions like @gordondavisson said, so even if you weren't passing the word "what" as a parameter to your function, you still wouldn't be able to print the word "chicken". So, in this case, the only possible way to use the parameter inside the function would be to assign $1 to a variable.

Sign up to request clarification or add additional context in comments.

1 Comment

It's not just shadowing -- variables are global unless declared otherwise, so when you run temp="hello" inside a function, you're writing to the global temp variable unless you previously ran local temp, declare temp, or typeset temp earlier in that same function.
0

#This should demostrate the situation somewhat

#! /bin/bash -f

# author: pitprok # ammended by: acs

# date:13Apr2024

# scriptname: scopeTest.sh

# =============================

temp="hi"

#==========================

phrase() {

  #local temp="bye"  # define temp to local scope
  echo "2 $temp"
  temp="hello"  # without local define, temp is global 
  echo "3 $temp"
   }

#=========== main ==============`

echo "1 $temp"

phase

`echo "4 $temp"`

# put this in a script and run it then un-comment line "local temp" and notice the difference on the re-run

1 hi 2 bye 3 hello 4 hi

1 hi 2 hi 3 hello 4 hello

1 Comment

Stack Overflow supports multi-line code blocks with either of the approaches in GitHub-flavored markdown. Use that instead of formatting each line separately.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.