`$@` vs. `$*` behavior [duplicate]

The name of the pictureThe name of the pictureThe name of the pictureClash 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...", where c is the first character of the value of the IFS 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









share|improve this question















marked as duplicate by Scott, ilkkachu bash
Users with the  bash badge can single-handedly close bash questions as duplicates and reopen them as needed.

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 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














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...", where c is the first character of the value of the IFS 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









share|improve this question















marked as duplicate by Scott, ilkkachu bash
Users with the  bash badge can single-handedly close bash questions as duplicates and reopen them as needed.

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 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












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...", where c is the first character of the value of the IFS 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









share|improve this question
















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...", where c is the first character of the value of the IFS 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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 26 at 21:10

























asked Nov 26 at 20:12









De Novo

1034




1034




marked as duplicate by Scott, ilkkachu bash
Users with the  bash badge can single-handedly close bash questions as duplicates and reopen them as needed.

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 bash
Users with the  bash badge can single-handedly close bash questions as duplicates and reopen them as needed.

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 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
















  • 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















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










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.






share|improve this answer






















  • ...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

















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.






share|improve this answer



























    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.






    share|improve this answer





























      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.






      share|improve this answer






















      • ...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














      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.






      share|improve this answer






















      • ...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












      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.






      share|improve this answer














      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.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 27 at 13:23

























      answered Nov 26 at 20:22









      Lewis M

      7505




      7505











      • ...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
















      • ...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















      ...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












      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.






      share|improve this answer
























        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.






        share|improve this answer






















          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.






          share|improve this answer












          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.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 26 at 20:22









          choroba

          26k44570




          26k44570




















              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.






              share|improve this answer


























                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.






                share|improve this answer
























                  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.






                  share|improve this answer














                  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.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 26 at 20:32

























                  answered Nov 26 at 20:26









                  Kusalananda

                  118k16223364




                  118k16223364












                      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?