Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Arguments and String Manipulation  ›  Lesson

"$@", $* and shift

$@ 14 min"$@" expands to every argument as a separate word, "$*" joins them into one string, and shift discards the first argument so the rest move down.

"$@", $* and shift

backup.sh should accept any number of folders: ./backup.sh ~/notes "My Photos" ~/code. You cannot write $1 $2 $3 when you do not know how many will come. Bash has two ways to say "all the arguments", and only one of them is safe.

The rule

"$@" keeps each argument whole; shift drops the first.

For the call ./backup.sh ~/notes "My Photos":

Written as Becomes
"$@" two words: /home/asha/notes and My Photos
"$*" one word: /home/asha/notes My Photos
$@ or $* unquoted three words: /home/asha/notes, My, Photos

"$@" is exactly what the caller typed, argument for argument. It is the right choice almost every time you pass arguments on to another command:

tar -czf "$archive" "$@"

"$*" is for when you want one string, such as a log message: echo "Arguments: $*".

shift throws away $1 and moves every other argument down one place. $# drops by one. shift 2 drops two. This is how a script peels off leading options before handling the rest:

label="$1"          # save it first
shift               # now "$@" is only the folders
tar -czf "$dest/$label.tar.gz" "$@"

The shortcut

Picture the arguments as cards in a row. "$@" hands over the row, every card separate. "$*" tapes the cards into one strip. Unquoted, the cards are cut apart at every space. shift takes the first card off the table, so the others slide left.

./backup.sh weekly ~/notes "My Photos"Step 1 of 4
  1. Before shift

    $1 is weekly, $2 is /home/asha/notes, $3 is My Photos, and $# is 3.

Drills

Answer fast — trust the rule.

quick drill

A script is run as ./s "a b" c. How many words does "$@" expand to?

quick drill

For the same call, ./s "a b" c, what does "$*" expand to?

quick drill

For ./s "a b" c, how many words does unquoted $@ give?

quick drill

A script gets x y z, runs shift, then echo "$1 $#". What prints?

quick drill

Why must label="$1" come before shift?

Remember

  • "$@" keeps each argument whole; shift drops the first.
  • Cards: "$@" is the row, "$*" the taped strip, unquoted is cut apart.
  • Save $1 before you shift it away.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainOne label, many folders

backup.sh should be called as ./backup.sh weekly ~/notes "My Photos" ~/code: a label first, then any number of folders. Write the lines that take the label and archive all the folders, and explain what shift does and why "$@" is the right expansion.