Why is $1 in a function not printing the script's first argument?
Solution 1
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.
Solution 2
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).
Related videos on Youtube
pietro letti
curious, very curious. self-taught. toward LPIC-1 system administrator.
Updated on September 18, 2022Comments
-
pietro letti almost 2 years
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?
-
Rui F Ribeiro almost 6 yearsbecause you forgot the $1 when calling print_something. Please try to include text in the question and not in the title.
-
pietro letti almost 6 yearsthanks. 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?
-
pipe almost 6 yearsWhen 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.
-
Codingale almost 6 years@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.
-
-
RudiC almost 6 yearsYou 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, theecho
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) -
Stéphane Chazelas almost 6 yearsUsing
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
... -
Kusalananda almost 6 yearsPassing
"$@"
toprint_something
, as it's currently written, would still only print the first of the arguments though. -
weirdan almost 6 yearsBut 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.
-
Kusalananda almost 6 yearsWell, just thinking there's no point in passing all the arguments along if only the first one is being used.
-
allo almost 6 years@Kusalananda
"$@"
has quotes, making it a single argument toprint_something
. -
Kusalananda almost 6 years@allo No.
"$*"
would be a single string (joined on the first character of$IFS
) while"$@"
would be a list of individually quoted elements. -
ygreaney almost 6 years@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. -
Admin about 2 yearsI think you are saying the opposite while meaning the correct. The positional arguments are those passed to that function, not that in the global scope of the whole script. For that reason
print_something
cannot see the$1
of the script, as it is not passed to the function. -
Admin about 2 years«The positional arguments are those passed to that function, not that in the global scope» — They are both positional (
$N
), but they do refer to different data, depending on the scope