Iterate through command line arguments in Bash

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
1
down vote

favorite












Can someone explain the difference between these two code blocks? I would think Block #2 would output the same as Block #1 but it does not. Can someone explain why?



# ./arguments.sh hello my name is X


Block #1



for i
do
echo $i
done


Output:



hello
my
name
is
X


Block #2



args=$#
for (( i=1; i<=$args; i+=1 ))
do
echo $i
done


Output:



1
2
3
4
5









share|improve this question



















  • 2




    Replace in second example echo $i by echo $i $1; shift to get more confused or enlightened.
    – Cyrus
    Jan 2 '16 at 21:31










  • @Cyrus Yes, I also found while (( "$#" )); do echo $1; shift; done It served its purpose; confusion. I would still like to know why Block #2 does not produce the same output as Block #1 :)
    – jes516
    Jan 2 '16 at 21:42






  • 1




    @jes516 in #2, you are explicitly creating a variable i and assigning an integer index to it; in #1, the shell is implicitly assigning each positional parameter in turn to i. See the for name [ [ in [ word ... ] ] ; ] do list ; done construct in the Compound commands section of man bash.
    – steeldriver
    Jan 2 '16 at 22:19














up vote
1
down vote

favorite












Can someone explain the difference between these two code blocks? I would think Block #2 would output the same as Block #1 but it does not. Can someone explain why?



# ./arguments.sh hello my name is X


Block #1



for i
do
echo $i
done


Output:



hello
my
name
is
X


Block #2



args=$#
for (( i=1; i<=$args; i+=1 ))
do
echo $i
done


Output:



1
2
3
4
5









share|improve this question



















  • 2




    Replace in second example echo $i by echo $i $1; shift to get more confused or enlightened.
    – Cyrus
    Jan 2 '16 at 21:31










  • @Cyrus Yes, I also found while (( "$#" )); do echo $1; shift; done It served its purpose; confusion. I would still like to know why Block #2 does not produce the same output as Block #1 :)
    – jes516
    Jan 2 '16 at 21:42






  • 1




    @jes516 in #2, you are explicitly creating a variable i and assigning an integer index to it; in #1, the shell is implicitly assigning each positional parameter in turn to i. See the for name [ [ in [ word ... ] ] ; ] do list ; done construct in the Compound commands section of man bash.
    – steeldriver
    Jan 2 '16 at 22:19












up vote
1
down vote

favorite









up vote
1
down vote

favorite











Can someone explain the difference between these two code blocks? I would think Block #2 would output the same as Block #1 but it does not. Can someone explain why?



# ./arguments.sh hello my name is X


Block #1



for i
do
echo $i
done


Output:



hello
my
name
is
X


Block #2



args=$#
for (( i=1; i<=$args; i+=1 ))
do
echo $i
done


Output:



1
2
3
4
5









share|improve this question















Can someone explain the difference between these two code blocks? I would think Block #2 would output the same as Block #1 but it does not. Can someone explain why?



# ./arguments.sh hello my name is X


Block #1



for i
do
echo $i
done


Output:



hello
my
name
is
X


Block #2



args=$#
for (( i=1; i<=$args; i+=1 ))
do
echo $i
done


Output:



1
2
3
4
5






bash






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Aug 31 at 16:44









Rui F Ribeiro

36.8k1272117




36.8k1272117










asked Jan 2 '16 at 21:17









jes516

3231620




3231620







  • 2




    Replace in second example echo $i by echo $i $1; shift to get more confused or enlightened.
    – Cyrus
    Jan 2 '16 at 21:31










  • @Cyrus Yes, I also found while (( "$#" )); do echo $1; shift; done It served its purpose; confusion. I would still like to know why Block #2 does not produce the same output as Block #1 :)
    – jes516
    Jan 2 '16 at 21:42






  • 1




    @jes516 in #2, you are explicitly creating a variable i and assigning an integer index to it; in #1, the shell is implicitly assigning each positional parameter in turn to i. See the for name [ [ in [ word ... ] ] ; ] do list ; done construct in the Compound commands section of man bash.
    – steeldriver
    Jan 2 '16 at 22:19












  • 2




    Replace in second example echo $i by echo $i $1; shift to get more confused or enlightened.
    – Cyrus
    Jan 2 '16 at 21:31










  • @Cyrus Yes, I also found while (( "$#" )); do echo $1; shift; done It served its purpose; confusion. I would still like to know why Block #2 does not produce the same output as Block #1 :)
    – jes516
    Jan 2 '16 at 21:42






  • 1




    @jes516 in #2, you are explicitly creating a variable i and assigning an integer index to it; in #1, the shell is implicitly assigning each positional parameter in turn to i. See the for name [ [ in [ word ... ] ] ; ] do list ; done construct in the Compound commands section of man bash.
    – steeldriver
    Jan 2 '16 at 22:19







2




2




Replace in second example echo $i by echo $i $1; shift to get more confused or enlightened.
– Cyrus
Jan 2 '16 at 21:31




Replace in second example echo $i by echo $i $1; shift to get more confused or enlightened.
– Cyrus
Jan 2 '16 at 21:31












@Cyrus Yes, I also found while (( "$#" )); do echo $1; shift; done It served its purpose; confusion. I would still like to know why Block #2 does not produce the same output as Block #1 :)
– jes516
Jan 2 '16 at 21:42




@Cyrus Yes, I also found while (( "$#" )); do echo $1; shift; done It served its purpose; confusion. I would still like to know why Block #2 does not produce the same output as Block #1 :)
– jes516
Jan 2 '16 at 21:42




1




1




@jes516 in #2, you are explicitly creating a variable i and assigning an integer index to it; in #1, the shell is implicitly assigning each positional parameter in turn to i. See the for name [ [ in [ word ... ] ] ; ] do list ; done construct in the Compound commands section of man bash.
– steeldriver
Jan 2 '16 at 22:19




@jes516 in #2, you are explicitly creating a variable i and assigning an integer index to it; in #1, the shell is implicitly assigning each positional parameter in turn to i. See the for name [ [ in [ word ... ] ] ; ] do list ; done construct in the Compound commands section of man bash.
– steeldriver
Jan 2 '16 at 22:19










2 Answers
2






active

oldest

votes

















up vote
3
down vote



accepted










roaima's answer answers the question that you actually asked:




Q: What is the difference between these two code blocks? 
Why do they give different output?



A: The first loop is iterating over the command line arguments;
the second one is iterating over the argument numbers (indices).




... although I presume that you would have figured that much out
for yourself in another six to eight minutes — it's kind-of obvious.
You probably want the second program to do something like



echo $$i # This doesn't do what you want.


to display the argument that is indexed by the number
that is stored in variable i (and referenced as $i). 
As noted in the comment, that doesn't do what you want. 
(It does do something;
I encourage you to experiment and figure out what it does.) 
But this is close to something that does work:



eval echo $$i # Don't do this.


or, equivalently,



eval echo '$'"$i" # Don't do this.


These commands



  • get the value of i (one of the numbers 1, 2, 3, ...)

  • stick a $ in front of it, forming $1, $2, $3, etc.

  • use the eval command to say, "take this command line
    that I've just constructed, and evaluate it as if I had typed it.

So that would have the effect of executing



echo $1
echo $2
echo $3
︙


But, as the comments suggest, you should try to avoid this. 
eval can be dangerous if the input is anything other than plain words. 
Search this site; you'll find plenty of explanations of that.



But there is a fairly safe way to get the second program
to do the same thing the first one does: change



echo $i


to



echo $!i


OK, first of all, $i is pretty much the same as $i. 
The ! gives you an effect similar to that of the eval command —
$!x looks up the value of x (i.e., $x or $x)
and uses that as the name of the variable to look up. 
So, if x=foo, then $!x is the same as $foo. 
The above code does the same thing with i,
fetching the parameter whose name is the value of i.



By the way, you should always quote all references to shell variables
(e.g., "$i", "$#", "$args", "$i" and "$!i")
unless you have a good reason not to,
and you’re sure you know what you’re doing.






share|improve this answer






















  • Just so I am clear, bash is looking for the variable $1, $2, etc... where the dollar sign is part of the variable name. For example I did, args="$#"; a="$1"; b="$2"; echo "$a"; echo "$b" and that worked. I thought bash was looking for the variable 1, 2, etc... where the dollar sign was part of the syntax (for lack of better terms).
    – jes516
    Jan 3 '16 at 4:31











  • I'd say you were right the first time.  If you have a variable named a, at the risk of being redundant, its name is a.  You set it by saying a=…; e.g., a=aardvark or a="$1".  You access it (e.g., in an echo command) with "$a" or "$a", so the $ and $… are part of the syntax (and that’s a perfectly appropriate term).  $1, $2, etc… are slightly different from $a, $b, etc…, but not much.
    – G-Man
    Jan 3 '16 at 22:33











  • Perfect, I appreciate the insight. While I have your attention (if you don't mind) why does for i; do echo $i; done work as well to print arguments? Does bash automatically run that code block for each argument? I am used to seeing for i in list; ...
    – jes516
    Jan 4 '16 at 3:08










  • You understand for i in "$1" "$2" "$3" "$4" "$5"; do …, right?  But the problem is that you don’t know in advance how many arguments there are (i.e., how many there are going to be).  roaima’s answer brushed up against this without delving into it.  $@ (which, above all other $ expressions, should always be quoted) is a magic token that expands to the list of arguments, however long or short that is. (You can, and should, read about this, the $… syntax, and other things in sh/bash documentation;  … (Cont’d)
    – G-Man
    Jan 4 '16 at 6:39











  • (Cont’d) …  e.g., what you get if you type man sh or man bash (if that doesn’t work for you, try this), the Bash Reference Manual, the POSIX specification for Shell Command Language, and other references.)  And for i; do … is a special shorthand for for i in "$@"; do … — which is equivalent to for i in "$1" "$2" "$3" "$4" "$5"; do … (if you have five arguments).
    – G-Man
    Jan 4 '16 at 6:41

















up vote
4
down vote













The first block iterates (implicitly) across the command line arguments "$@"



for i in "$@" # same as your "for i"
do
echo "$i"
done


The second block iterates explicitly across the number of arguments, printing the index as it goes:



args=$# # number of command line args
for (( i=1; i<=$args; i+=1 )) # loop from 1 to N (where N is number of args)
do
echo $i
done


Given that, as per your example, $# is 5, then the $i variable will take the values 1, 2, 3, 4, 5.



As pointed out in another (now deleted) answer, you can reference the command line arguments by index like this:



args=$#
for (( i=1; i<=$args; i++ ))
do
echo "$i - $!i"
done





share|improve this answer






















  • Just to expand on my comment below, echo "$i - $!i" is echoing the variable i - the variable $i, where i is the number and $i evaluates to the "shell variable" $1..
    – jes516
    Jan 3 '16 at 4:34










Your Answer







StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f252900%2fiterate-through-command-line-arguments-in-bash%23new-answer', 'question_page');

);

Post as a guest






























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
3
down vote



accepted










roaima's answer answers the question that you actually asked:




Q: What is the difference between these two code blocks? 
Why do they give different output?



A: The first loop is iterating over the command line arguments;
the second one is iterating over the argument numbers (indices).




... although I presume that you would have figured that much out
for yourself in another six to eight minutes — it's kind-of obvious.
You probably want the second program to do something like



echo $$i # This doesn't do what you want.


to display the argument that is indexed by the number
that is stored in variable i (and referenced as $i). 
As noted in the comment, that doesn't do what you want. 
(It does do something;
I encourage you to experiment and figure out what it does.) 
But this is close to something that does work:



eval echo $$i # Don't do this.


or, equivalently,



eval echo '$'"$i" # Don't do this.


These commands



  • get the value of i (one of the numbers 1, 2, 3, ...)

  • stick a $ in front of it, forming $1, $2, $3, etc.

  • use the eval command to say, "take this command line
    that I've just constructed, and evaluate it as if I had typed it.

So that would have the effect of executing



echo $1
echo $2
echo $3
︙


But, as the comments suggest, you should try to avoid this. 
eval can be dangerous if the input is anything other than plain words. 
Search this site; you'll find plenty of explanations of that.



But there is a fairly safe way to get the second program
to do the same thing the first one does: change



echo $i


to



echo $!i


OK, first of all, $i is pretty much the same as $i. 
The ! gives you an effect similar to that of the eval command —
$!x looks up the value of x (i.e., $x or $x)
and uses that as the name of the variable to look up. 
So, if x=foo, then $!x is the same as $foo. 
The above code does the same thing with i,
fetching the parameter whose name is the value of i.



By the way, you should always quote all references to shell variables
(e.g., "$i", "$#", "$args", "$i" and "$!i")
unless you have a good reason not to,
and you’re sure you know what you’re doing.






share|improve this answer






















  • Just so I am clear, bash is looking for the variable $1, $2, etc... where the dollar sign is part of the variable name. For example I did, args="$#"; a="$1"; b="$2"; echo "$a"; echo "$b" and that worked. I thought bash was looking for the variable 1, 2, etc... where the dollar sign was part of the syntax (for lack of better terms).
    – jes516
    Jan 3 '16 at 4:31











  • I'd say you were right the first time.  If you have a variable named a, at the risk of being redundant, its name is a.  You set it by saying a=…; e.g., a=aardvark or a="$1".  You access it (e.g., in an echo command) with "$a" or "$a", so the $ and $… are part of the syntax (and that’s a perfectly appropriate term).  $1, $2, etc… are slightly different from $a, $b, etc…, but not much.
    – G-Man
    Jan 3 '16 at 22:33











  • Perfect, I appreciate the insight. While I have your attention (if you don't mind) why does for i; do echo $i; done work as well to print arguments? Does bash automatically run that code block for each argument? I am used to seeing for i in list; ...
    – jes516
    Jan 4 '16 at 3:08










  • You understand for i in "$1" "$2" "$3" "$4" "$5"; do …, right?  But the problem is that you don’t know in advance how many arguments there are (i.e., how many there are going to be).  roaima’s answer brushed up against this without delving into it.  $@ (which, above all other $ expressions, should always be quoted) is a magic token that expands to the list of arguments, however long or short that is. (You can, and should, read about this, the $… syntax, and other things in sh/bash documentation;  … (Cont’d)
    – G-Man
    Jan 4 '16 at 6:39











  • (Cont’d) …  e.g., what you get if you type man sh or man bash (if that doesn’t work for you, try this), the Bash Reference Manual, the POSIX specification for Shell Command Language, and other references.)  And for i; do … is a special shorthand for for i in "$@"; do … — which is equivalent to for i in "$1" "$2" "$3" "$4" "$5"; do … (if you have five arguments).
    – G-Man
    Jan 4 '16 at 6:41














up vote
3
down vote



accepted










roaima's answer answers the question that you actually asked:




Q: What is the difference between these two code blocks? 
Why do they give different output?



A: The first loop is iterating over the command line arguments;
the second one is iterating over the argument numbers (indices).




... although I presume that you would have figured that much out
for yourself in another six to eight minutes — it's kind-of obvious.
You probably want the second program to do something like



echo $$i # This doesn't do what you want.


to display the argument that is indexed by the number
that is stored in variable i (and referenced as $i). 
As noted in the comment, that doesn't do what you want. 
(It does do something;
I encourage you to experiment and figure out what it does.) 
But this is close to something that does work:



eval echo $$i # Don't do this.


or, equivalently,



eval echo '$'"$i" # Don't do this.


These commands



  • get the value of i (one of the numbers 1, 2, 3, ...)

  • stick a $ in front of it, forming $1, $2, $3, etc.

  • use the eval command to say, "take this command line
    that I've just constructed, and evaluate it as if I had typed it.

So that would have the effect of executing



echo $1
echo $2
echo $3
︙


But, as the comments suggest, you should try to avoid this. 
eval can be dangerous if the input is anything other than plain words. 
Search this site; you'll find plenty of explanations of that.



But there is a fairly safe way to get the second program
to do the same thing the first one does: change



echo $i


to



echo $!i


OK, first of all, $i is pretty much the same as $i. 
The ! gives you an effect similar to that of the eval command —
$!x looks up the value of x (i.e., $x or $x)
and uses that as the name of the variable to look up. 
So, if x=foo, then $!x is the same as $foo. 
The above code does the same thing with i,
fetching the parameter whose name is the value of i.



By the way, you should always quote all references to shell variables
(e.g., "$i", "$#", "$args", "$i" and "$!i")
unless you have a good reason not to,
and you’re sure you know what you’re doing.






share|improve this answer






















  • Just so I am clear, bash is looking for the variable $1, $2, etc... where the dollar sign is part of the variable name. For example I did, args="$#"; a="$1"; b="$2"; echo "$a"; echo "$b" and that worked. I thought bash was looking for the variable 1, 2, etc... where the dollar sign was part of the syntax (for lack of better terms).
    – jes516
    Jan 3 '16 at 4:31











  • I'd say you were right the first time.  If you have a variable named a, at the risk of being redundant, its name is a.  You set it by saying a=…; e.g., a=aardvark or a="$1".  You access it (e.g., in an echo command) with "$a" or "$a", so the $ and $… are part of the syntax (and that’s a perfectly appropriate term).  $1, $2, etc… are slightly different from $a, $b, etc…, but not much.
    – G-Man
    Jan 3 '16 at 22:33











  • Perfect, I appreciate the insight. While I have your attention (if you don't mind) why does for i; do echo $i; done work as well to print arguments? Does bash automatically run that code block for each argument? I am used to seeing for i in list; ...
    – jes516
    Jan 4 '16 at 3:08










  • You understand for i in "$1" "$2" "$3" "$4" "$5"; do …, right?  But the problem is that you don’t know in advance how many arguments there are (i.e., how many there are going to be).  roaima’s answer brushed up against this without delving into it.  $@ (which, above all other $ expressions, should always be quoted) is a magic token that expands to the list of arguments, however long or short that is. (You can, and should, read about this, the $… syntax, and other things in sh/bash documentation;  … (Cont’d)
    – G-Man
    Jan 4 '16 at 6:39











  • (Cont’d) …  e.g., what you get if you type man sh or man bash (if that doesn’t work for you, try this), the Bash Reference Manual, the POSIX specification for Shell Command Language, and other references.)  And for i; do … is a special shorthand for for i in "$@"; do … — which is equivalent to for i in "$1" "$2" "$3" "$4" "$5"; do … (if you have five arguments).
    – G-Man
    Jan 4 '16 at 6:41












up vote
3
down vote



accepted







up vote
3
down vote



accepted






roaima's answer answers the question that you actually asked:




Q: What is the difference between these two code blocks? 
Why do they give different output?



A: The first loop is iterating over the command line arguments;
the second one is iterating over the argument numbers (indices).




... although I presume that you would have figured that much out
for yourself in another six to eight minutes — it's kind-of obvious.
You probably want the second program to do something like



echo $$i # This doesn't do what you want.


to display the argument that is indexed by the number
that is stored in variable i (and referenced as $i). 
As noted in the comment, that doesn't do what you want. 
(It does do something;
I encourage you to experiment and figure out what it does.) 
But this is close to something that does work:



eval echo $$i # Don't do this.


or, equivalently,



eval echo '$'"$i" # Don't do this.


These commands



  • get the value of i (one of the numbers 1, 2, 3, ...)

  • stick a $ in front of it, forming $1, $2, $3, etc.

  • use the eval command to say, "take this command line
    that I've just constructed, and evaluate it as if I had typed it.

So that would have the effect of executing



echo $1
echo $2
echo $3
︙


But, as the comments suggest, you should try to avoid this. 
eval can be dangerous if the input is anything other than plain words. 
Search this site; you'll find plenty of explanations of that.



But there is a fairly safe way to get the second program
to do the same thing the first one does: change



echo $i


to



echo $!i


OK, first of all, $i is pretty much the same as $i. 
The ! gives you an effect similar to that of the eval command —
$!x looks up the value of x (i.e., $x or $x)
and uses that as the name of the variable to look up. 
So, if x=foo, then $!x is the same as $foo. 
The above code does the same thing with i,
fetching the parameter whose name is the value of i.



By the way, you should always quote all references to shell variables
(e.g., "$i", "$#", "$args", "$i" and "$!i")
unless you have a good reason not to,
and you’re sure you know what you’re doing.






share|improve this answer














roaima's answer answers the question that you actually asked:




Q: What is the difference between these two code blocks? 
Why do they give different output?



A: The first loop is iterating over the command line arguments;
the second one is iterating over the argument numbers (indices).




... although I presume that you would have figured that much out
for yourself in another six to eight minutes — it's kind-of obvious.
You probably want the second program to do something like



echo $$i # This doesn't do what you want.


to display the argument that is indexed by the number
that is stored in variable i (and referenced as $i). 
As noted in the comment, that doesn't do what you want. 
(It does do something;
I encourage you to experiment and figure out what it does.) 
But this is close to something that does work:



eval echo $$i # Don't do this.


or, equivalently,



eval echo '$'"$i" # Don't do this.


These commands



  • get the value of i (one of the numbers 1, 2, 3, ...)

  • stick a $ in front of it, forming $1, $2, $3, etc.

  • use the eval command to say, "take this command line
    that I've just constructed, and evaluate it as if I had typed it.

So that would have the effect of executing



echo $1
echo $2
echo $3
︙


But, as the comments suggest, you should try to avoid this. 
eval can be dangerous if the input is anything other than plain words. 
Search this site; you'll find plenty of explanations of that.



But there is a fairly safe way to get the second program
to do the same thing the first one does: change



echo $i


to



echo $!i


OK, first of all, $i is pretty much the same as $i. 
The ! gives you an effect similar to that of the eval command —
$!x looks up the value of x (i.e., $x or $x)
and uses that as the name of the variable to look up. 
So, if x=foo, then $!x is the same as $foo. 
The above code does the same thing with i,
fetching the parameter whose name is the value of i.



By the way, you should always quote all references to shell variables
(e.g., "$i", "$#", "$args", "$i" and "$!i")
unless you have a good reason not to,
and you’re sure you know what you’re doing.







share|improve this answer














share|improve this answer



share|improve this answer








edited Apr 13 '17 at 12:36









Community♦

1




1










answered Jan 2 '16 at 23:09









G-Man

11.8k92658




11.8k92658











  • Just so I am clear, bash is looking for the variable $1, $2, etc... where the dollar sign is part of the variable name. For example I did, args="$#"; a="$1"; b="$2"; echo "$a"; echo "$b" and that worked. I thought bash was looking for the variable 1, 2, etc... where the dollar sign was part of the syntax (for lack of better terms).
    – jes516
    Jan 3 '16 at 4:31











  • I'd say you were right the first time.  If you have a variable named a, at the risk of being redundant, its name is a.  You set it by saying a=…; e.g., a=aardvark or a="$1".  You access it (e.g., in an echo command) with "$a" or "$a", so the $ and $… are part of the syntax (and that’s a perfectly appropriate term).  $1, $2, etc… are slightly different from $a, $b, etc…, but not much.
    – G-Man
    Jan 3 '16 at 22:33











  • Perfect, I appreciate the insight. While I have your attention (if you don't mind) why does for i; do echo $i; done work as well to print arguments? Does bash automatically run that code block for each argument? I am used to seeing for i in list; ...
    – jes516
    Jan 4 '16 at 3:08










  • You understand for i in "$1" "$2" "$3" "$4" "$5"; do …, right?  But the problem is that you don’t know in advance how many arguments there are (i.e., how many there are going to be).  roaima’s answer brushed up against this without delving into it.  $@ (which, above all other $ expressions, should always be quoted) is a magic token that expands to the list of arguments, however long or short that is. (You can, and should, read about this, the $… syntax, and other things in sh/bash documentation;  … (Cont’d)
    – G-Man
    Jan 4 '16 at 6:39











  • (Cont’d) …  e.g., what you get if you type man sh or man bash (if that doesn’t work for you, try this), the Bash Reference Manual, the POSIX specification for Shell Command Language, and other references.)  And for i; do … is a special shorthand for for i in "$@"; do … — which is equivalent to for i in "$1" "$2" "$3" "$4" "$5"; do … (if you have five arguments).
    – G-Man
    Jan 4 '16 at 6:41
















  • Just so I am clear, bash is looking for the variable $1, $2, etc... where the dollar sign is part of the variable name. For example I did, args="$#"; a="$1"; b="$2"; echo "$a"; echo "$b" and that worked. I thought bash was looking for the variable 1, 2, etc... where the dollar sign was part of the syntax (for lack of better terms).
    – jes516
    Jan 3 '16 at 4:31











  • I'd say you were right the first time.  If you have a variable named a, at the risk of being redundant, its name is a.  You set it by saying a=…; e.g., a=aardvark or a="$1".  You access it (e.g., in an echo command) with "$a" or "$a", so the $ and $… are part of the syntax (and that’s a perfectly appropriate term).  $1, $2, etc… are slightly different from $a, $b, etc…, but not much.
    – G-Man
    Jan 3 '16 at 22:33











  • Perfect, I appreciate the insight. While I have your attention (if you don't mind) why does for i; do echo $i; done work as well to print arguments? Does bash automatically run that code block for each argument? I am used to seeing for i in list; ...
    – jes516
    Jan 4 '16 at 3:08










  • You understand for i in "$1" "$2" "$3" "$4" "$5"; do …, right?  But the problem is that you don’t know in advance how many arguments there are (i.e., how many there are going to be).  roaima’s answer brushed up against this without delving into it.  $@ (which, above all other $ expressions, should always be quoted) is a magic token that expands to the list of arguments, however long or short that is. (You can, and should, read about this, the $… syntax, and other things in sh/bash documentation;  … (Cont’d)
    – G-Man
    Jan 4 '16 at 6:39











  • (Cont’d) …  e.g., what you get if you type man sh or man bash (if that doesn’t work for you, try this), the Bash Reference Manual, the POSIX specification for Shell Command Language, and other references.)  And for i; do … is a special shorthand for for i in "$@"; do … — which is equivalent to for i in "$1" "$2" "$3" "$4" "$5"; do … (if you have five arguments).
    – G-Man
    Jan 4 '16 at 6:41















Just so I am clear, bash is looking for the variable $1, $2, etc... where the dollar sign is part of the variable name. For example I did, args="$#"; a="$1"; b="$2"; echo "$a"; echo "$b" and that worked. I thought bash was looking for the variable 1, 2, etc... where the dollar sign was part of the syntax (for lack of better terms).
– jes516
Jan 3 '16 at 4:31





Just so I am clear, bash is looking for the variable $1, $2, etc... where the dollar sign is part of the variable name. For example I did, args="$#"; a="$1"; b="$2"; echo "$a"; echo "$b" and that worked. I thought bash was looking for the variable 1, 2, etc... where the dollar sign was part of the syntax (for lack of better terms).
– jes516
Jan 3 '16 at 4:31













I'd say you were right the first time.  If you have a variable named a, at the risk of being redundant, its name is a.  You set it by saying a=…; e.g., a=aardvark or a="$1".  You access it (e.g., in an echo command) with "$a" or "$a", so the $ and $… are part of the syntax (and that’s a perfectly appropriate term).  $1, $2, etc… are slightly different from $a, $b, etc…, but not much.
– G-Man
Jan 3 '16 at 22:33





I'd say you were right the first time.  If you have a variable named a, at the risk of being redundant, its name is a.  You set it by saying a=…; e.g., a=aardvark or a="$1".  You access it (e.g., in an echo command) with "$a" or "$a", so the $ and $… are part of the syntax (and that’s a perfectly appropriate term).  $1, $2, etc… are slightly different from $a, $b, etc…, but not much.
– G-Man
Jan 3 '16 at 22:33













Perfect, I appreciate the insight. While I have your attention (if you don't mind) why does for i; do echo $i; done work as well to print arguments? Does bash automatically run that code block for each argument? I am used to seeing for i in list; ...
– jes516
Jan 4 '16 at 3:08




Perfect, I appreciate the insight. While I have your attention (if you don't mind) why does for i; do echo $i; done work as well to print arguments? Does bash automatically run that code block for each argument? I am used to seeing for i in list; ...
– jes516
Jan 4 '16 at 3:08












You understand for i in "$1" "$2" "$3" "$4" "$5"; do …, right?  But the problem is that you don’t know in advance how many arguments there are (i.e., how many there are going to be).  roaima’s answer brushed up against this without delving into it.  $@ (which, above all other $ expressions, should always be quoted) is a magic token that expands to the list of arguments, however long or short that is. (You can, and should, read about this, the $… syntax, and other things in sh/bash documentation;  … (Cont’d)
– G-Man
Jan 4 '16 at 6:39





You understand for i in "$1" "$2" "$3" "$4" "$5"; do …, right?  But the problem is that you don’t know in advance how many arguments there are (i.e., how many there are going to be).  roaima’s answer brushed up against this without delving into it.  $@ (which, above all other $ expressions, should always be quoted) is a magic token that expands to the list of arguments, however long or short that is. (You can, and should, read about this, the $… syntax, and other things in sh/bash documentation;  … (Cont’d)
– G-Man
Jan 4 '16 at 6:39













(Cont’d) …  e.g., what you get if you type man sh or man bash (if that doesn’t work for you, try this), the Bash Reference Manual, the POSIX specification for Shell Command Language, and other references.)  And for i; do … is a special shorthand for for i in "$@"; do … — which is equivalent to for i in "$1" "$2" "$3" "$4" "$5"; do … (if you have five arguments).
– G-Man
Jan 4 '16 at 6:41




(Cont’d) …  e.g., what you get if you type man sh or man bash (if that doesn’t work for you, try this), the Bash Reference Manual, the POSIX specification for Shell Command Language, and other references.)  And for i; do … is a special shorthand for for i in "$@"; do … — which is equivalent to for i in "$1" "$2" "$3" "$4" "$5"; do … (if you have five arguments).
– G-Man
Jan 4 '16 at 6:41












up vote
4
down vote













The first block iterates (implicitly) across the command line arguments "$@"



for i in "$@" # same as your "for i"
do
echo "$i"
done


The second block iterates explicitly across the number of arguments, printing the index as it goes:



args=$# # number of command line args
for (( i=1; i<=$args; i+=1 )) # loop from 1 to N (where N is number of args)
do
echo $i
done


Given that, as per your example, $# is 5, then the $i variable will take the values 1, 2, 3, 4, 5.



As pointed out in another (now deleted) answer, you can reference the command line arguments by index like this:



args=$#
for (( i=1; i<=$args; i++ ))
do
echo "$i - $!i"
done





share|improve this answer






















  • Just to expand on my comment below, echo "$i - $!i" is echoing the variable i - the variable $i, where i is the number and $i evaluates to the "shell variable" $1..
    – jes516
    Jan 3 '16 at 4:34














up vote
4
down vote













The first block iterates (implicitly) across the command line arguments "$@"



for i in "$@" # same as your "for i"
do
echo "$i"
done


The second block iterates explicitly across the number of arguments, printing the index as it goes:



args=$# # number of command line args
for (( i=1; i<=$args; i+=1 )) # loop from 1 to N (where N is number of args)
do
echo $i
done


Given that, as per your example, $# is 5, then the $i variable will take the values 1, 2, 3, 4, 5.



As pointed out in another (now deleted) answer, you can reference the command line arguments by index like this:



args=$#
for (( i=1; i<=$args; i++ ))
do
echo "$i - $!i"
done





share|improve this answer






















  • Just to expand on my comment below, echo "$i - $!i" is echoing the variable i - the variable $i, where i is the number and $i evaluates to the "shell variable" $1..
    – jes516
    Jan 3 '16 at 4:34












up vote
4
down vote










up vote
4
down vote









The first block iterates (implicitly) across the command line arguments "$@"



for i in "$@" # same as your "for i"
do
echo "$i"
done


The second block iterates explicitly across the number of arguments, printing the index as it goes:



args=$# # number of command line args
for (( i=1; i<=$args; i+=1 )) # loop from 1 to N (where N is number of args)
do
echo $i
done


Given that, as per your example, $# is 5, then the $i variable will take the values 1, 2, 3, 4, 5.



As pointed out in another (now deleted) answer, you can reference the command line arguments by index like this:



args=$#
for (( i=1; i<=$args; i++ ))
do
echo "$i - $!i"
done





share|improve this answer














The first block iterates (implicitly) across the command line arguments "$@"



for i in "$@" # same as your "for i"
do
echo "$i"
done


The second block iterates explicitly across the number of arguments, printing the index as it goes:



args=$# # number of command line args
for (( i=1; i<=$args; i+=1 )) # loop from 1 to N (where N is number of args)
do
echo $i
done


Given that, as per your example, $# is 5, then the $i variable will take the values 1, 2, 3, 4, 5.



As pointed out in another (now deleted) answer, you can reference the command line arguments by index like this:



args=$#
for (( i=1; i<=$args; i++ ))
do
echo "$i - $!i"
done






share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 2 '16 at 23:30

























answered Jan 2 '16 at 22:33









roaima

40.5k547110




40.5k547110











  • Just to expand on my comment below, echo "$i - $!i" is echoing the variable i - the variable $i, where i is the number and $i evaluates to the "shell variable" $1..
    – jes516
    Jan 3 '16 at 4:34
















  • Just to expand on my comment below, echo "$i - $!i" is echoing the variable i - the variable $i, where i is the number and $i evaluates to the "shell variable" $1..
    – jes516
    Jan 3 '16 at 4:34















Just to expand on my comment below, echo "$i - $!i" is echoing the variable i - the variable $i, where i is the number and $i evaluates to the "shell variable" $1..
– jes516
Jan 3 '16 at 4:34




Just to expand on my comment below, echo "$i - $!i" is echoing the variable i - the variable $i, where i is the number and $i evaluates to the "shell variable" $1..
– jes516
Jan 3 '16 at 4:34

















 

draft saved


draft discarded















































 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f252900%2fiterate-through-command-line-arguments-in-bash%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

How to check contact read email or not when send email to Individual?

Displaying single band from multi-band raster using QGIS

How many registers does an x86_64 CPU actually have?