16

Why doesn't echo $1 print $1 in this simple bash script?

#!/bin/bash
# function.sh
print_something () {
echo $1
}
print_something

$ ./function.sh 123  -> why doesn't it print '123' as a result?
4
  • 6
    because you forgot the $1 when calling print_something. Please try to include text in the question and not in the title. Commented Aug 27, 2018 at 8:45
  • thanks. What should be the echo argument if I need to insert in the script the commands: print_something "$1"; print_something "$2"; and maybe more? Commented Aug 27, 2018 at 9:26
  • 13
    When I saw this in HNQ I thought you were printing dollar-bills and hoped to read some juicy story about how your printer detects that you're printing fake money. Commented Aug 27, 2018 at 13:59
  • @pipe I've had that happen to me before, for some reason it refuses to print anything not just the ones with the anti-printing preventions. Commented Aug 27, 2018 at 16:40

2 Answers 2

43

Positional parameters refer to the script's arguments in the main level of the script, but to function arguments in function body. So

print_something Something

would actually print Something.

If you want to pass the script's arguments to a function, you must do that explicitly. Use

print_something "$1"

to pass the first argument, or

print_something "$@"

to pass all of them, though the function in example only uses the first one.

8
  • 1
    Passing "$@" to print_something, as it's currently written, would still only print the first of the arguments though. Commented Aug 27, 2018 at 9:21
  • 13
    But the point was to show how to pass all arguments, I presume. The fact that the function, as it stands, only uses the first of its arguments is a bit irrelevant. Commented Aug 27, 2018 at 9:36
  • Well, just thinking there's no point in passing all the arguments along if only the first one is being used. Commented Aug 27, 2018 at 9:50
  • 15
    @allo No. "$*" would be a single string (joined on the first character of $IFS) while "$@" would be a list of individually quoted elements. Commented Aug 27, 2018 at 11:41
  • 6
    @Kusalananda the point of telling someone who wants to pass the command-line parameters to a function to use "$@", even if in this case there is only one such parameter, is to cover all such cases. If the OP decides to add a second parameter, there's nothing to change in the function invocation. And everyone else who reads this will learn the right way to do it to avoid having to re-do it later, too. Commented Aug 27, 2018 at 18:35
11

This is because a called function gets its own set of positional parameters, independent of the parent's / caller's set. Try

print_something "$1"

(and echo "$1", or even better printf '%s\n' "$1", remember to quote parameter expansions and that echo can't be used for arbitrary data).

2
  • You need to become clearer what you are talking about. The caller's $1 is generally different from the function's $1, although they CAN become the same if used like proposed above. If I get you right, the echo can stay the same (echo $1) when the function is called with single parameters (print_something $2 takes the caller's $1 and "makes" it $1 inside the function) Commented Aug 27, 2018 at 9:07
  • 6
    Using echo $1 doesn't make sense unless you want $1 to be treated as a $IFS-delimited list of file patterns to expand. echo "$1" would make more sense, though would not output the content of $1 for values of $1 like -nene, -EE... Commented Aug 27, 2018 at 9:16

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.