0

Say I create a file ~/myScript.sh:

#!/bin/sh

for myVar; do
    echo "Hi"
done

If I execute bash myScript with no arguments I'll get nothing but if I'll execute it with one or more arguments I'll get the output per the number of these variables (the variable seems to make the script dependent in passed arguments):

bash ~/myScript.sh arg0 arg1

The for loop, which is based on the undefined variable myVar, would apply arg0 and arg1 to itself (sorry if this phrasing is lousy) and I'll get this output:

Hi

Hi

(one "Hi" per argument).


I originally assumed that one for loop works with one argument so if I would have myVar_0 and myVar_1 with arg0 and arg1, then myVar_0 will work with arg_0 and myVar_1 will work with arg1 but I further tested and I was wrong --- all for loops worked with all arguments:

#!/bin/sh

for myVar_0; do
    echo "Hi"
done

for myVar_1; do
    echo "Hello"
done

will return in bash myScript arg0 arg1:

Hi

hello

Hi

hello

Sidenote: I assume that if would want "1 argument per 1 for loop" I just need to use a Bash function for local scope.

My question

What is the name of this "all arguments per all for loops" matching that Bash does?

2

myVar is not undefined if the script is called with positional parameters. From man bash:

for name [ [ in [ word ... ] ] ; ] do list ; done
[...] If the in word is omitted, the for command executes list once for each positional parameter that is set

But you do not use $myVar.

for myVar; do
    echo "$myVar"
done
  • Thx. Regarding your code example, why wouldn't you say it's undefined in the sense that it doesn't have any values? I mean, I did this echo of $myVar and got nothing so at least philosophically I can call it "undefined" (just sharing a way for me to look at it). – Arcticooling Jan 14 '18 at 13:13
  • 1
    @Arcticooling It is in a certain way undefined if the script is called without positional parameters. But even in that case it is well defined what happens. – Hauke Laging Jan 14 '18 at 13:34
1

The for loop in Bash / POSIX shell is similar to e.g. the for loop in Python: the loop variable takes the listed values, one-by-one, and the loop body runs once for each value.

So this:

for x in foo bar; do
    echo "$x"
done
echo finally x is "$x" 

is similar to

x=foo        # assign value
echo "$x"    # loop body
x=bar        # same with the second value...
echo "$x"
echo finally x is "$x"   # this isn't part of the loop body

except that you don't need to repeat the loop body. If we have an array variable A, for x in "${A[@]}"; do... loops over the values of the array. Similarly for x in "$@"; do... loops over the positional parameters, i.e. the command line arguments, since they're what "$@" expands to. And for x; do is basically just shorthand for for x in "$@"; do

So, this would print all the command line arguments:

for x; do                 # or: for x in "$@"; do
    printf "%s\n" "$x"
done

To access the arguments directly by index, use $1 for the first, $2 for the second argument, etc...

printf "the first arg is %s and the second is %s\n" "$1" "$2"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.