`$@` vs. `$*` behavior [duplicate]
Clash Royale CLAN TAG#URR8PPP
up vote
0
down vote
favorite
This question already has an answer here:
What is the difference between $* and $@?
7 answers
Unexpected outcome of a=“$@”
1 answer
The bash manual says:
Regarding: $*
When the expansion occurs within double quotes, it expands to a single word with the value of each parameter separated by the first character of the
IFS
special variable. That is,"$*"
is equivalent to"$1c$2c..."
, wherec
is the first character of the value of theIFS
variable.
Regarding: $@
When the expansion occurs within double quotes, each parameter expands to a separate word. That is,
"$@"
is equivalent to"$1" "$2" ...
.
Provided the first character of the value of the IFS
variable is in fact a single space, I can't seem to come up with an example where these two special parameters would produce different behavior. Can anyone provide me with an example (again, without changing IFS
) where they would produce different behavior?
My own test, which still baffles me a bit, is as follows:
#!/usr/bin/env bash
# File: test.sh
# set foo and bar in the global environment to $@ and $*
test_expansion ()
foo="$@"
bar="$*"
Now testing:
. test.sh
test_expansion a b c d
# foo is $@
# bar is $*
for e in "$foo"; do
echo "$e"
done
# a b c d
for e in "$bar"; do
echo "$e"
done
# a b c d
bash bash-expansion
marked as duplicate by Scott, ilkkachu
StackExchange.ready(function()
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();
);
);
);
Nov 26 at 21:15
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
add a comment |
up vote
0
down vote
favorite
This question already has an answer here:
What is the difference between $* and $@?
7 answers
Unexpected outcome of a=“$@”
1 answer
The bash manual says:
Regarding: $*
When the expansion occurs within double quotes, it expands to a single word with the value of each parameter separated by the first character of the
IFS
special variable. That is,"$*"
is equivalent to"$1c$2c..."
, wherec
is the first character of the value of theIFS
variable.
Regarding: $@
When the expansion occurs within double quotes, each parameter expands to a separate word. That is,
"$@"
is equivalent to"$1" "$2" ...
.
Provided the first character of the value of the IFS
variable is in fact a single space, I can't seem to come up with an example where these two special parameters would produce different behavior. Can anyone provide me with an example (again, without changing IFS
) where they would produce different behavior?
My own test, which still baffles me a bit, is as follows:
#!/usr/bin/env bash
# File: test.sh
# set foo and bar in the global environment to $@ and $*
test_expansion ()
foo="$@"
bar="$*"
Now testing:
. test.sh
test_expansion a b c d
# foo is $@
# bar is $*
for e in "$foo"; do
echo "$e"
done
# a b c d
for e in "$bar"; do
echo "$e"
done
# a b c d
bash bash-expansion
marked as duplicate by Scott, ilkkachu
StackExchange.ready(function()
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();
);
);
);
Nov 26 at 21:15
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
Did you read all the way through Mikel's answer? Did you read the first half of Wojtek Rzepala's answer? Most importantly, did you read Carlos Campderrós's answer? It's probably the best of the bunch, and it doesn't mentionIFS
at all.
– Scott
Nov 26 at 20:56
1
Yeah, Stack Exchange's search engine sucks. Half of the time I want to search Stack Exchange, I use Google; see, for example, this search. … P.S. Gilles's answer, although a late addition, is pretty good, too. (Gilles's answers usually are.)
– Scott
Nov 26 at 21:10
1
The fact that it's an assignment in your test is the key here. Splitting the value on the right hand side of an assignment doesn't make much sense, since the assigned value can only be a single string anyway. So the fact that"$@"
assigns to separate words doesn't apply there. That's discussed in Unexpected outcome of a=“$@”.
– ilkkachu
Nov 26 at 21:19
1
Right.$@
is special. Once you assign it to an ordinary variable, you lose that special quality. But try using arrays:foo=("$@")
/bar=("$*")
/set | grep '^foo='
/set | grep '^bar='
.
– Scott
Nov 26 at 21:36
@Scott thanks. That entirely resolves things. It was somehow unsatisfying to think, oh, it just doesn't work when you assign it to a variable, which, I think added to the general opacity of bash.
– De Novo
Nov 26 at 21:42
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
This question already has an answer here:
What is the difference between $* and $@?
7 answers
Unexpected outcome of a=“$@”
1 answer
The bash manual says:
Regarding: $*
When the expansion occurs within double quotes, it expands to a single word with the value of each parameter separated by the first character of the
IFS
special variable. That is,"$*"
is equivalent to"$1c$2c..."
, wherec
is the first character of the value of theIFS
variable.
Regarding: $@
When the expansion occurs within double quotes, each parameter expands to a separate word. That is,
"$@"
is equivalent to"$1" "$2" ...
.
Provided the first character of the value of the IFS
variable is in fact a single space, I can't seem to come up with an example where these two special parameters would produce different behavior. Can anyone provide me with an example (again, without changing IFS
) where they would produce different behavior?
My own test, which still baffles me a bit, is as follows:
#!/usr/bin/env bash
# File: test.sh
# set foo and bar in the global environment to $@ and $*
test_expansion ()
foo="$@"
bar="$*"
Now testing:
. test.sh
test_expansion a b c d
# foo is $@
# bar is $*
for e in "$foo"; do
echo "$e"
done
# a b c d
for e in "$bar"; do
echo "$e"
done
# a b c d
bash bash-expansion
This question already has an answer here:
What is the difference between $* and $@?
7 answers
Unexpected outcome of a=“$@”
1 answer
The bash manual says:
Regarding: $*
When the expansion occurs within double quotes, it expands to a single word with the value of each parameter separated by the first character of the
IFS
special variable. That is,"$*"
is equivalent to"$1c$2c..."
, wherec
is the first character of the value of theIFS
variable.
Regarding: $@
When the expansion occurs within double quotes, each parameter expands to a separate word. That is,
"$@"
is equivalent to"$1" "$2" ...
.
Provided the first character of the value of the IFS
variable is in fact a single space, I can't seem to come up with an example where these two special parameters would produce different behavior. Can anyone provide me with an example (again, without changing IFS
) where they would produce different behavior?
My own test, which still baffles me a bit, is as follows:
#!/usr/bin/env bash
# File: test.sh
# set foo and bar in the global environment to $@ and $*
test_expansion ()
foo="$@"
bar="$*"
Now testing:
. test.sh
test_expansion a b c d
# foo is $@
# bar is $*
for e in "$foo"; do
echo "$e"
done
# a b c d
for e in "$bar"; do
echo "$e"
done
# a b c d
This question already has an answer here:
What is the difference between $* and $@?
7 answers
Unexpected outcome of a=“$@”
1 answer
bash bash-expansion
bash bash-expansion
edited Nov 26 at 21:10
asked Nov 26 at 20:12
De Novo
1034
1034
marked as duplicate by Scott, ilkkachu
StackExchange.ready(function()
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();
);
);
);
Nov 26 at 21:15
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
marked as duplicate by Scott, ilkkachu
StackExchange.ready(function()
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();
);
);
);
Nov 26 at 21:15
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
Did you read all the way through Mikel's answer? Did you read the first half of Wojtek Rzepala's answer? Most importantly, did you read Carlos Campderrós's answer? It's probably the best of the bunch, and it doesn't mentionIFS
at all.
– Scott
Nov 26 at 20:56
1
Yeah, Stack Exchange's search engine sucks. Half of the time I want to search Stack Exchange, I use Google; see, for example, this search. … P.S. Gilles's answer, although a late addition, is pretty good, too. (Gilles's answers usually are.)
– Scott
Nov 26 at 21:10
1
The fact that it's an assignment in your test is the key here. Splitting the value on the right hand side of an assignment doesn't make much sense, since the assigned value can only be a single string anyway. So the fact that"$@"
assigns to separate words doesn't apply there. That's discussed in Unexpected outcome of a=“$@”.
– ilkkachu
Nov 26 at 21:19
1
Right.$@
is special. Once you assign it to an ordinary variable, you lose that special quality. But try using arrays:foo=("$@")
/bar=("$*")
/set | grep '^foo='
/set | grep '^bar='
.
– Scott
Nov 26 at 21:36
@Scott thanks. That entirely resolves things. It was somehow unsatisfying to think, oh, it just doesn't work when you assign it to a variable, which, I think added to the general opacity of bash.
– De Novo
Nov 26 at 21:42
add a comment |
Did you read all the way through Mikel's answer? Did you read the first half of Wojtek Rzepala's answer? Most importantly, did you read Carlos Campderrós's answer? It's probably the best of the bunch, and it doesn't mentionIFS
at all.
– Scott
Nov 26 at 20:56
1
Yeah, Stack Exchange's search engine sucks. Half of the time I want to search Stack Exchange, I use Google; see, for example, this search. … P.S. Gilles's answer, although a late addition, is pretty good, too. (Gilles's answers usually are.)
– Scott
Nov 26 at 21:10
1
The fact that it's an assignment in your test is the key here. Splitting the value on the right hand side of an assignment doesn't make much sense, since the assigned value can only be a single string anyway. So the fact that"$@"
assigns to separate words doesn't apply there. That's discussed in Unexpected outcome of a=“$@”.
– ilkkachu
Nov 26 at 21:19
1
Right.$@
is special. Once you assign it to an ordinary variable, you lose that special quality. But try using arrays:foo=("$@")
/bar=("$*")
/set | grep '^foo='
/set | grep '^bar='
.
– Scott
Nov 26 at 21:36
@Scott thanks. That entirely resolves things. It was somehow unsatisfying to think, oh, it just doesn't work when you assign it to a variable, which, I think added to the general opacity of bash.
– De Novo
Nov 26 at 21:42
Did you read all the way through Mikel's answer? Did you read the first half of Wojtek Rzepala's answer? Most importantly, did you read Carlos Campderrós's answer? It's probably the best of the bunch, and it doesn't mention
IFS
at all.– Scott
Nov 26 at 20:56
Did you read all the way through Mikel's answer? Did you read the first half of Wojtek Rzepala's answer? Most importantly, did you read Carlos Campderrós's answer? It's probably the best of the bunch, and it doesn't mention
IFS
at all.– Scott
Nov 26 at 20:56
1
1
Yeah, Stack Exchange's search engine sucks. Half of the time I want to search Stack Exchange, I use Google; see, for example, this search. … P.S. Gilles's answer, although a late addition, is pretty good, too. (Gilles's answers usually are.)
– Scott
Nov 26 at 21:10
Yeah, Stack Exchange's search engine sucks. Half of the time I want to search Stack Exchange, I use Google; see, for example, this search. … P.S. Gilles's answer, although a late addition, is pretty good, too. (Gilles's answers usually are.)
– Scott
Nov 26 at 21:10
1
1
The fact that it's an assignment in your test is the key here. Splitting the value on the right hand side of an assignment doesn't make much sense, since the assigned value can only be a single string anyway. So the fact that
"$@"
assigns to separate words doesn't apply there. That's discussed in Unexpected outcome of a=“$@”.– ilkkachu
Nov 26 at 21:19
The fact that it's an assignment in your test is the key here. Splitting the value on the right hand side of an assignment doesn't make much sense, since the assigned value can only be a single string anyway. So the fact that
"$@"
assigns to separate words doesn't apply there. That's discussed in Unexpected outcome of a=“$@”.– ilkkachu
Nov 26 at 21:19
1
1
Right.
$@
is special. Once you assign it to an ordinary variable, you lose that special quality. But try using arrays: foo=("$@")
/ bar=("$*")
/ set | grep '^foo='
/ set | grep '^bar='
.– Scott
Nov 26 at 21:36
Right.
$@
is special. Once you assign it to an ordinary variable, you lose that special quality. But try using arrays: foo=("$@")
/ bar=("$*")
/ set | grep '^foo='
/ set | grep '^bar='
.– Scott
Nov 26 at 21:36
@Scott thanks. That entirely resolves things. It was somehow unsatisfying to think, oh, it just doesn't work when you assign it to a variable, which, I think added to the general opacity of bash.
– De Novo
Nov 26 at 21:42
@Scott thanks. That entirely resolves things. It was somehow unsatisfying to think, oh, it just doesn't work when you assign it to a variable, which, I think added to the general opacity of bash.
– De Novo
Nov 26 at 21:42
add a comment |
3 Answers
3
active
oldest
votes
up vote
3
down vote
accepted
The difference comes in when you have arguments you pass in on the command line with IFS characters in them (e.g. an argument with a space). To see the difference, look at this script:
#!/bin/bash
echo 'Here is $*'
for x in "$*"; do
echo " !$x!"
done
echo ""
echo 'And here is $@'
for x in "$@"; do
echo " !$x!"
done
exit 0
Now, look at the difference when you pass in an argument with a space.
./testspace01.sh "This is" a test
Here is $*
!This is a test!
And here is $@
!This is!
!a!
!test!
Hope this helps.
UPDATE
Ah, assigning what was passed in on the command line to a variable brings its own little quirks. :)
Remember, everything that was passed in on the command line is an array. So, assigning the array to a string gives you something different than signing to an array. And, handling the array is different depending on if you are using the star or the asterisk. Here is an updated version of my script.
#!/bin/bash
s_star="$*"
echo 'Here is s_star'
for x in "$s_star"; do
echo " !$x!"
done
a_star=("$*")
echo ""
echo 'Here is a_star'
for x in "$a_star"; do
echo " !$x!"
done
s_at="$@"
echo ""
echo 'Here is s_at'
for x in "$s_at"; do
echo " !$x!"
done
a_at=("$@")
echo ""
echo 'Here is a_at (using star)'
for x in "$a_at[*]"; do
echo " !$x!"
done
echo ""
echo 'Here is a_at (using at)'
for x in "$a_at[@]"; do
echo " !$x!"
done
exit 0
Here is the output:
./testspace02.sh "This is" a test
Here is s_star
!This is a test!
Here is a_star
!This is a test!
Here is s_at
!This is a test!
Here is a_at (using star)
!This is a test!
Here is a_at (using at)
!This is!
!a!
!test!
As you can see, there is different behaviors.
Hope this helps clarify things further for you.
...or justprintf '!%s!n' "$*"
vsprintf '!%s!n' "$@"
– ilkkachu
Nov 26 at 21:12
This acts as I expected it would on reading the documentation, but when I ran my own test (putting the values for"$@"
and"$*"
into a global variable and then manipulating them in an interactive session), it doesn't behave this way.
– De Novo
Nov 26 at 21:18
add a comment |
up vote
3
down vote
Try this:
#!/bin/bash
show-difference ()
for e in "$@" ; do
printf '<%s>n' "$e"
done
for e in "$*" ; do
printf '[%s]n' "$e"
done
show-difference a..h
Output:
<a>
<b>
<c>
<d>
<e>
<f>
<g>
<h>
[a b c d e f g h]
"$*"
is a single word, while "$@"
expands to all the parameters as single words. Moreover, "$@"
works correctly even if the arguments contain the first character of IFS.
add a comment |
up vote
0
down vote
set -- "hello there" bumblebee
printf '%sn' "$@"
printf '%sn' "$*"
Result:
hello there
bumblebee
followed by
hello there bumblebee
This shows that "$@"
generates a list of individually quoted elements while "$*"
generates a single quoted string.
add a comment |
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
accepted
The difference comes in when you have arguments you pass in on the command line with IFS characters in them (e.g. an argument with a space). To see the difference, look at this script:
#!/bin/bash
echo 'Here is $*'
for x in "$*"; do
echo " !$x!"
done
echo ""
echo 'And here is $@'
for x in "$@"; do
echo " !$x!"
done
exit 0
Now, look at the difference when you pass in an argument with a space.
./testspace01.sh "This is" a test
Here is $*
!This is a test!
And here is $@
!This is!
!a!
!test!
Hope this helps.
UPDATE
Ah, assigning what was passed in on the command line to a variable brings its own little quirks. :)
Remember, everything that was passed in on the command line is an array. So, assigning the array to a string gives you something different than signing to an array. And, handling the array is different depending on if you are using the star or the asterisk. Here is an updated version of my script.
#!/bin/bash
s_star="$*"
echo 'Here is s_star'
for x in "$s_star"; do
echo " !$x!"
done
a_star=("$*")
echo ""
echo 'Here is a_star'
for x in "$a_star"; do
echo " !$x!"
done
s_at="$@"
echo ""
echo 'Here is s_at'
for x in "$s_at"; do
echo " !$x!"
done
a_at=("$@")
echo ""
echo 'Here is a_at (using star)'
for x in "$a_at[*]"; do
echo " !$x!"
done
echo ""
echo 'Here is a_at (using at)'
for x in "$a_at[@]"; do
echo " !$x!"
done
exit 0
Here is the output:
./testspace02.sh "This is" a test
Here is s_star
!This is a test!
Here is a_star
!This is a test!
Here is s_at
!This is a test!
Here is a_at (using star)
!This is a test!
Here is a_at (using at)
!This is!
!a!
!test!
As you can see, there is different behaviors.
Hope this helps clarify things further for you.
...or justprintf '!%s!n' "$*"
vsprintf '!%s!n' "$@"
– ilkkachu
Nov 26 at 21:12
This acts as I expected it would on reading the documentation, but when I ran my own test (putting the values for"$@"
and"$*"
into a global variable and then manipulating them in an interactive session), it doesn't behave this way.
– De Novo
Nov 26 at 21:18
add a comment |
up vote
3
down vote
accepted
The difference comes in when you have arguments you pass in on the command line with IFS characters in them (e.g. an argument with a space). To see the difference, look at this script:
#!/bin/bash
echo 'Here is $*'
for x in "$*"; do
echo " !$x!"
done
echo ""
echo 'And here is $@'
for x in "$@"; do
echo " !$x!"
done
exit 0
Now, look at the difference when you pass in an argument with a space.
./testspace01.sh "This is" a test
Here is $*
!This is a test!
And here is $@
!This is!
!a!
!test!
Hope this helps.
UPDATE
Ah, assigning what was passed in on the command line to a variable brings its own little quirks. :)
Remember, everything that was passed in on the command line is an array. So, assigning the array to a string gives you something different than signing to an array. And, handling the array is different depending on if you are using the star or the asterisk. Here is an updated version of my script.
#!/bin/bash
s_star="$*"
echo 'Here is s_star'
for x in "$s_star"; do
echo " !$x!"
done
a_star=("$*")
echo ""
echo 'Here is a_star'
for x in "$a_star"; do
echo " !$x!"
done
s_at="$@"
echo ""
echo 'Here is s_at'
for x in "$s_at"; do
echo " !$x!"
done
a_at=("$@")
echo ""
echo 'Here is a_at (using star)'
for x in "$a_at[*]"; do
echo " !$x!"
done
echo ""
echo 'Here is a_at (using at)'
for x in "$a_at[@]"; do
echo " !$x!"
done
exit 0
Here is the output:
./testspace02.sh "This is" a test
Here is s_star
!This is a test!
Here is a_star
!This is a test!
Here is s_at
!This is a test!
Here is a_at (using star)
!This is a test!
Here is a_at (using at)
!This is!
!a!
!test!
As you can see, there is different behaviors.
Hope this helps clarify things further for you.
...or justprintf '!%s!n' "$*"
vsprintf '!%s!n' "$@"
– ilkkachu
Nov 26 at 21:12
This acts as I expected it would on reading the documentation, but when I ran my own test (putting the values for"$@"
and"$*"
into a global variable and then manipulating them in an interactive session), it doesn't behave this way.
– De Novo
Nov 26 at 21:18
add a comment |
up vote
3
down vote
accepted
up vote
3
down vote
accepted
The difference comes in when you have arguments you pass in on the command line with IFS characters in them (e.g. an argument with a space). To see the difference, look at this script:
#!/bin/bash
echo 'Here is $*'
for x in "$*"; do
echo " !$x!"
done
echo ""
echo 'And here is $@'
for x in "$@"; do
echo " !$x!"
done
exit 0
Now, look at the difference when you pass in an argument with a space.
./testspace01.sh "This is" a test
Here is $*
!This is a test!
And here is $@
!This is!
!a!
!test!
Hope this helps.
UPDATE
Ah, assigning what was passed in on the command line to a variable brings its own little quirks. :)
Remember, everything that was passed in on the command line is an array. So, assigning the array to a string gives you something different than signing to an array. And, handling the array is different depending on if you are using the star or the asterisk. Here is an updated version of my script.
#!/bin/bash
s_star="$*"
echo 'Here is s_star'
for x in "$s_star"; do
echo " !$x!"
done
a_star=("$*")
echo ""
echo 'Here is a_star'
for x in "$a_star"; do
echo " !$x!"
done
s_at="$@"
echo ""
echo 'Here is s_at'
for x in "$s_at"; do
echo " !$x!"
done
a_at=("$@")
echo ""
echo 'Here is a_at (using star)'
for x in "$a_at[*]"; do
echo " !$x!"
done
echo ""
echo 'Here is a_at (using at)'
for x in "$a_at[@]"; do
echo " !$x!"
done
exit 0
Here is the output:
./testspace02.sh "This is" a test
Here is s_star
!This is a test!
Here is a_star
!This is a test!
Here is s_at
!This is a test!
Here is a_at (using star)
!This is a test!
Here is a_at (using at)
!This is!
!a!
!test!
As you can see, there is different behaviors.
Hope this helps clarify things further for you.
The difference comes in when you have arguments you pass in on the command line with IFS characters in them (e.g. an argument with a space). To see the difference, look at this script:
#!/bin/bash
echo 'Here is $*'
for x in "$*"; do
echo " !$x!"
done
echo ""
echo 'And here is $@'
for x in "$@"; do
echo " !$x!"
done
exit 0
Now, look at the difference when you pass in an argument with a space.
./testspace01.sh "This is" a test
Here is $*
!This is a test!
And here is $@
!This is!
!a!
!test!
Hope this helps.
UPDATE
Ah, assigning what was passed in on the command line to a variable brings its own little quirks. :)
Remember, everything that was passed in on the command line is an array. So, assigning the array to a string gives you something different than signing to an array. And, handling the array is different depending on if you are using the star or the asterisk. Here is an updated version of my script.
#!/bin/bash
s_star="$*"
echo 'Here is s_star'
for x in "$s_star"; do
echo " !$x!"
done
a_star=("$*")
echo ""
echo 'Here is a_star'
for x in "$a_star"; do
echo " !$x!"
done
s_at="$@"
echo ""
echo 'Here is s_at'
for x in "$s_at"; do
echo " !$x!"
done
a_at=("$@")
echo ""
echo 'Here is a_at (using star)'
for x in "$a_at[*]"; do
echo " !$x!"
done
echo ""
echo 'Here is a_at (using at)'
for x in "$a_at[@]"; do
echo " !$x!"
done
exit 0
Here is the output:
./testspace02.sh "This is" a test
Here is s_star
!This is a test!
Here is a_star
!This is a test!
Here is s_at
!This is a test!
Here is a_at (using star)
!This is a test!
Here is a_at (using at)
!This is!
!a!
!test!
As you can see, there is different behaviors.
Hope this helps clarify things further for you.
edited Nov 27 at 13:23
answered Nov 26 at 20:22
Lewis M
7505
7505
...or justprintf '!%s!n' "$*"
vsprintf '!%s!n' "$@"
– ilkkachu
Nov 26 at 21:12
This acts as I expected it would on reading the documentation, but when I ran my own test (putting the values for"$@"
and"$*"
into a global variable and then manipulating them in an interactive session), it doesn't behave this way.
– De Novo
Nov 26 at 21:18
add a comment |
...or justprintf '!%s!n' "$*"
vsprintf '!%s!n' "$@"
– ilkkachu
Nov 26 at 21:12
This acts as I expected it would on reading the documentation, but when I ran my own test (putting the values for"$@"
and"$*"
into a global variable and then manipulating them in an interactive session), it doesn't behave this way.
– De Novo
Nov 26 at 21:18
...or just
printf '!%s!n' "$*"
vs printf '!%s!n' "$@"
– ilkkachu
Nov 26 at 21:12
...or just
printf '!%s!n' "$*"
vs printf '!%s!n' "$@"
– ilkkachu
Nov 26 at 21:12
This acts as I expected it would on reading the documentation, but when I ran my own test (putting the values for
"$@"
and "$*"
into a global variable and then manipulating them in an interactive session), it doesn't behave this way.– De Novo
Nov 26 at 21:18
This acts as I expected it would on reading the documentation, but when I ran my own test (putting the values for
"$@"
and "$*"
into a global variable and then manipulating them in an interactive session), it doesn't behave this way.– De Novo
Nov 26 at 21:18
add a comment |
up vote
3
down vote
Try this:
#!/bin/bash
show-difference ()
for e in "$@" ; do
printf '<%s>n' "$e"
done
for e in "$*" ; do
printf '[%s]n' "$e"
done
show-difference a..h
Output:
<a>
<b>
<c>
<d>
<e>
<f>
<g>
<h>
[a b c d e f g h]
"$*"
is a single word, while "$@"
expands to all the parameters as single words. Moreover, "$@"
works correctly even if the arguments contain the first character of IFS.
add a comment |
up vote
3
down vote
Try this:
#!/bin/bash
show-difference ()
for e in "$@" ; do
printf '<%s>n' "$e"
done
for e in "$*" ; do
printf '[%s]n' "$e"
done
show-difference a..h
Output:
<a>
<b>
<c>
<d>
<e>
<f>
<g>
<h>
[a b c d e f g h]
"$*"
is a single word, while "$@"
expands to all the parameters as single words. Moreover, "$@"
works correctly even if the arguments contain the first character of IFS.
add a comment |
up vote
3
down vote
up vote
3
down vote
Try this:
#!/bin/bash
show-difference ()
for e in "$@" ; do
printf '<%s>n' "$e"
done
for e in "$*" ; do
printf '[%s]n' "$e"
done
show-difference a..h
Output:
<a>
<b>
<c>
<d>
<e>
<f>
<g>
<h>
[a b c d e f g h]
"$*"
is a single word, while "$@"
expands to all the parameters as single words. Moreover, "$@"
works correctly even if the arguments contain the first character of IFS.
Try this:
#!/bin/bash
show-difference ()
for e in "$@" ; do
printf '<%s>n' "$e"
done
for e in "$*" ; do
printf '[%s]n' "$e"
done
show-difference a..h
Output:
<a>
<b>
<c>
<d>
<e>
<f>
<g>
<h>
[a b c d e f g h]
"$*"
is a single word, while "$@"
expands to all the parameters as single words. Moreover, "$@"
works correctly even if the arguments contain the first character of IFS.
answered Nov 26 at 20:22
choroba
26k44570
26k44570
add a comment |
add a comment |
up vote
0
down vote
set -- "hello there" bumblebee
printf '%sn' "$@"
printf '%sn' "$*"
Result:
hello there
bumblebee
followed by
hello there bumblebee
This shows that "$@"
generates a list of individually quoted elements while "$*"
generates a single quoted string.
add a comment |
up vote
0
down vote
set -- "hello there" bumblebee
printf '%sn' "$@"
printf '%sn' "$*"
Result:
hello there
bumblebee
followed by
hello there bumblebee
This shows that "$@"
generates a list of individually quoted elements while "$*"
generates a single quoted string.
add a comment |
up vote
0
down vote
up vote
0
down vote
set -- "hello there" bumblebee
printf '%sn' "$@"
printf '%sn' "$*"
Result:
hello there
bumblebee
followed by
hello there bumblebee
This shows that "$@"
generates a list of individually quoted elements while "$*"
generates a single quoted string.
set -- "hello there" bumblebee
printf '%sn' "$@"
printf '%sn' "$*"
Result:
hello there
bumblebee
followed by
hello there bumblebee
This shows that "$@"
generates a list of individually quoted elements while "$*"
generates a single quoted string.
edited Nov 26 at 20:32
answered Nov 26 at 20:26
Kusalananda
118k16223364
118k16223364
add a comment |
add a comment |
Did you read all the way through Mikel's answer? Did you read the first half of Wojtek Rzepala's answer? Most importantly, did you read Carlos Campderrós's answer? It's probably the best of the bunch, and it doesn't mention
IFS
at all.– Scott
Nov 26 at 20:56
1
Yeah, Stack Exchange's search engine sucks. Half of the time I want to search Stack Exchange, I use Google; see, for example, this search. … P.S. Gilles's answer, although a late addition, is pretty good, too. (Gilles's answers usually are.)
– Scott
Nov 26 at 21:10
1
The fact that it's an assignment in your test is the key here. Splitting the value on the right hand side of an assignment doesn't make much sense, since the assigned value can only be a single string anyway. So the fact that
"$@"
assigns to separate words doesn't apply there. That's discussed in Unexpected outcome of a=“$@”.– ilkkachu
Nov 26 at 21:19
1
Right.
$@
is special. Once you assign it to an ordinary variable, you lose that special quality. But try using arrays:foo=("$@")
/bar=("$*")
/set | grep '^foo='
/set | grep '^bar='
.– Scott
Nov 26 at 21:36
@Scott thanks. That entirely resolves things. It was somehow unsatisfying to think, oh, it just doesn't work when you assign it to a variable, which, I think added to the general opacity of bash.
– De Novo
Nov 26 at 21:42