Bash âforâ loop without a âin foo barâ¦â part

Clash Royale CLAN TAG#URR8PPP
up vote
21
down vote
favorite
I was recently looking at some code that confused me because it works and I didn't expect it to. The code reduces to this example
#!/bin/bash
for var;
do
echo "$var"
done
When run with command line arguments is prints them
$ ./test a b c
a
b
c
It is this, that is (to me) unexpected. Why does this not result in an error because var is undefined ? Is using this considered 'good practice' ?
bash shell control-flow
add a comment |Â
up vote
21
down vote
favorite
I was recently looking at some code that confused me because it works and I didn't expect it to. The code reduces to this example
#!/bin/bash
for var;
do
echo "$var"
done
When run with command line arguments is prints them
$ ./test a b c
a
b
c
It is this, that is (to me) unexpected. Why does this not result in an error because var is undefined ? Is using this considered 'good practice' ?
bash shell control-flow
add a comment |Â
up vote
21
down vote
favorite
up vote
21
down vote
favorite
I was recently looking at some code that confused me because it works and I didn't expect it to. The code reduces to this example
#!/bin/bash
for var;
do
echo "$var"
done
When run with command line arguments is prints them
$ ./test a b c
a
b
c
It is this, that is (to me) unexpected. Why does this not result in an error because var is undefined ? Is using this considered 'good practice' ?
bash shell control-flow
I was recently looking at some code that confused me because it works and I didn't expect it to. The code reduces to this example
#!/bin/bash
for var;
do
echo "$var"
done
When run with command line arguments is prints them
$ ./test a b c
a
b
c
It is this, that is (to me) unexpected. Why does this not result in an error because var is undefined ? Is using this considered 'good practice' ?
bash shell control-flow
edited Jan 15 at 19:09
Gilles
506k11910021529
506k11910021529
asked Jan 15 at 16:55
user270650
1063
1063
add a comment |Â
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
26
down vote
for loops loop on the positional parameters if no in value1 value2... part is specified in all Bourne-like shells.
That was already the case in the Bourne shell from the late 70s, though in the Bourne shell, you'd need to omit that ; (you can also use for i do (except in some old ash versions where you need a newline before the do)).
See What is the purpose of the "do" keyword in Bash for loops? for more information including more surprising variants.
Doing:
for i
do
something with "$i"
done
is good practice. It's slightly more portable/reliable than the usually equivalent:
for i in "$@"; do
something with "$i"
done
for which the Bourne shell, ksh88 have some issues under some conditions (like when $# is 0 in some versions of the Bourne shell (which $1+"$@" instead of "$@" can work around) or when $IFS doesn't contain the space character in Bourne and ksh88), or when the nounset option is enabled and $# is 0 in some versions of some shells including bash (again with $1+"$@" as a work-around).
Had to read this thrice before my brain decided to stop editing out the repeated 'loop' at the start
â Three Diag
Jan 16 at 12:04
add a comment |Â
up vote
21
down vote
This is the default behavior, yes. It is documented in the help of the for keyword:
terdon@tpad ~ $ help for
for: for NAME [in WORDS ... ] ; do COMMANDS; done
Execute commands for each member in a list.
The `for' loop executes a sequence of commands for each member in a
list of items. If `in WORDS ...;' is not present, then `in "$@"' is
assumed. For each element in WORDS, NAME is set to that element, and
the COMMANDS are executed.
Exit Status:
Returns the status of the last command executed.
So, when you don't give it a list to iterate over, it will default to iterating over $@, the array of positional parameters (a, b and c in your example).
And this behavior is defined by POSIX so yes, it is considered "good practice" as far as that goes.
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
26
down vote
for loops loop on the positional parameters if no in value1 value2... part is specified in all Bourne-like shells.
That was already the case in the Bourne shell from the late 70s, though in the Bourne shell, you'd need to omit that ; (you can also use for i do (except in some old ash versions where you need a newline before the do)).
See What is the purpose of the "do" keyword in Bash for loops? for more information including more surprising variants.
Doing:
for i
do
something with "$i"
done
is good practice. It's slightly more portable/reliable than the usually equivalent:
for i in "$@"; do
something with "$i"
done
for which the Bourne shell, ksh88 have some issues under some conditions (like when $# is 0 in some versions of the Bourne shell (which $1+"$@" instead of "$@" can work around) or when $IFS doesn't contain the space character in Bourne and ksh88), or when the nounset option is enabled and $# is 0 in some versions of some shells including bash (again with $1+"$@" as a work-around).
Had to read this thrice before my brain decided to stop editing out the repeated 'loop' at the start
â Three Diag
Jan 16 at 12:04
add a comment |Â
up vote
26
down vote
for loops loop on the positional parameters if no in value1 value2... part is specified in all Bourne-like shells.
That was already the case in the Bourne shell from the late 70s, though in the Bourne shell, you'd need to omit that ; (you can also use for i do (except in some old ash versions where you need a newline before the do)).
See What is the purpose of the "do" keyword in Bash for loops? for more information including more surprising variants.
Doing:
for i
do
something with "$i"
done
is good practice. It's slightly more portable/reliable than the usually equivalent:
for i in "$@"; do
something with "$i"
done
for which the Bourne shell, ksh88 have some issues under some conditions (like when $# is 0 in some versions of the Bourne shell (which $1+"$@" instead of "$@" can work around) or when $IFS doesn't contain the space character in Bourne and ksh88), or when the nounset option is enabled and $# is 0 in some versions of some shells including bash (again with $1+"$@" as a work-around).
Had to read this thrice before my brain decided to stop editing out the repeated 'loop' at the start
â Three Diag
Jan 16 at 12:04
add a comment |Â
up vote
26
down vote
up vote
26
down vote
for loops loop on the positional parameters if no in value1 value2... part is specified in all Bourne-like shells.
That was already the case in the Bourne shell from the late 70s, though in the Bourne shell, you'd need to omit that ; (you can also use for i do (except in some old ash versions where you need a newline before the do)).
See What is the purpose of the "do" keyword in Bash for loops? for more information including more surprising variants.
Doing:
for i
do
something with "$i"
done
is good practice. It's slightly more portable/reliable than the usually equivalent:
for i in "$@"; do
something with "$i"
done
for which the Bourne shell, ksh88 have some issues under some conditions (like when $# is 0 in some versions of the Bourne shell (which $1+"$@" instead of "$@" can work around) or when $IFS doesn't contain the space character in Bourne and ksh88), or when the nounset option is enabled and $# is 0 in some versions of some shells including bash (again with $1+"$@" as a work-around).
for loops loop on the positional parameters if no in value1 value2... part is specified in all Bourne-like shells.
That was already the case in the Bourne shell from the late 70s, though in the Bourne shell, you'd need to omit that ; (you can also use for i do (except in some old ash versions where you need a newline before the do)).
See What is the purpose of the "do" keyword in Bash for loops? for more information including more surprising variants.
Doing:
for i
do
something with "$i"
done
is good practice. It's slightly more portable/reliable than the usually equivalent:
for i in "$@"; do
something with "$i"
done
for which the Bourne shell, ksh88 have some issues under some conditions (like when $# is 0 in some versions of the Bourne shell (which $1+"$@" instead of "$@" can work around) or when $IFS doesn't contain the space character in Bourne and ksh88), or when the nounset option is enabled and $# is 0 in some versions of some shells including bash (again with $1+"$@" as a work-around).
edited Jan 16 at 12:29
answered Jan 15 at 17:00
Stéphane Chazelas
281k53518849
281k53518849
Had to read this thrice before my brain decided to stop editing out the repeated 'loop' at the start
â Three Diag
Jan 16 at 12:04
add a comment |Â
Had to read this thrice before my brain decided to stop editing out the repeated 'loop' at the start
â Three Diag
Jan 16 at 12:04
Had to read this thrice before my brain decided to stop editing out the repeated 'loop' at the start
â Three Diag
Jan 16 at 12:04
Had to read this thrice before my brain decided to stop editing out the repeated 'loop' at the start
â Three Diag
Jan 16 at 12:04
add a comment |Â
up vote
21
down vote
This is the default behavior, yes. It is documented in the help of the for keyword:
terdon@tpad ~ $ help for
for: for NAME [in WORDS ... ] ; do COMMANDS; done
Execute commands for each member in a list.
The `for' loop executes a sequence of commands for each member in a
list of items. If `in WORDS ...;' is not present, then `in "$@"' is
assumed. For each element in WORDS, NAME is set to that element, and
the COMMANDS are executed.
Exit Status:
Returns the status of the last command executed.
So, when you don't give it a list to iterate over, it will default to iterating over $@, the array of positional parameters (a, b and c in your example).
And this behavior is defined by POSIX so yes, it is considered "good practice" as far as that goes.
add a comment |Â
up vote
21
down vote
This is the default behavior, yes. It is documented in the help of the for keyword:
terdon@tpad ~ $ help for
for: for NAME [in WORDS ... ] ; do COMMANDS; done
Execute commands for each member in a list.
The `for' loop executes a sequence of commands for each member in a
list of items. If `in WORDS ...;' is not present, then `in "$@"' is
assumed. For each element in WORDS, NAME is set to that element, and
the COMMANDS are executed.
Exit Status:
Returns the status of the last command executed.
So, when you don't give it a list to iterate over, it will default to iterating over $@, the array of positional parameters (a, b and c in your example).
And this behavior is defined by POSIX so yes, it is considered "good practice" as far as that goes.
add a comment |Â
up vote
21
down vote
up vote
21
down vote
This is the default behavior, yes. It is documented in the help of the for keyword:
terdon@tpad ~ $ help for
for: for NAME [in WORDS ... ] ; do COMMANDS; done
Execute commands for each member in a list.
The `for' loop executes a sequence of commands for each member in a
list of items. If `in WORDS ...;' is not present, then `in "$@"' is
assumed. For each element in WORDS, NAME is set to that element, and
the COMMANDS are executed.
Exit Status:
Returns the status of the last command executed.
So, when you don't give it a list to iterate over, it will default to iterating over $@, the array of positional parameters (a, b and c in your example).
And this behavior is defined by POSIX so yes, it is considered "good practice" as far as that goes.
This is the default behavior, yes. It is documented in the help of the for keyword:
terdon@tpad ~ $ help for
for: for NAME [in WORDS ... ] ; do COMMANDS; done
Execute commands for each member in a list.
The `for' loop executes a sequence of commands for each member in a
list of items. If `in WORDS ...;' is not present, then `in "$@"' is
assumed. For each element in WORDS, NAME is set to that element, and
the COMMANDS are executed.
Exit Status:
Returns the status of the last command executed.
So, when you don't give it a list to iterate over, it will default to iterating over $@, the array of positional parameters (a, b and c in your example).
And this behavior is defined by POSIX so yes, it is considered "good practice" as far as that goes.
answered Jan 15 at 16:59
terdonâ¦
122k28230403
122k28230403
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f417292%2fbash-for-loop-without-a-in-foo-bar-part%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password