Ravindra BagaleCourses & study guides मराठी Track your progress

Shell Scripting Complete 3: Script Input with Arguments, $@, shift, read and getopts

A script becomes useful when it can take input: a file name, a server, a number of days. This chapter shows the three ways a script gets input: from the user with read, from the command line with $1, $2, $@ and shift, and as options like -v or -d DIR with getopts. You will also learn to print a usage message, check input, read passwords safely and read from a pipe or a here-document.

What you'll learn in this chapter

  • Ask the user with read -p, -s and -t
  • Use $1, $#, $@ and shift
  • Know "$@" vs "$*"
  • Parse options with getopts
  • Print usage and validate input
  • Read from stdin, pipes and here-docs

1. An everyday example: ordering at a chai stall

Why do we need this?

At a chai stall you can order in three ways. You can wait for the owner to ask 'kiti?' and answer (read). You can say everything at once, 'two cutting, one without sugar' (arguments). Or you can use the menu codes, 'C2 -S' (options). A good stall understands all three and tells you the menu if you say something wrong.

What is it?

Owner asks = read. Saying it all at once = $1 $2. Count of items = $#. Menu codes = getopts options. Showing the menu = usage message. Wrong order = exit 2.

How to do it (step by step)

How a good script takes inputParse options with getoptsshift away the optionsCheck $# for required argumentsValidate each valueShow usage and exit 2 if badRun the real work
Check first, work later.

2. read: ask the user

Why do we need this?

Some scripts need a value only a person can give, like a ticket number or a yes/no.

What is it?

read name waits for a line and stores it in name. -p 'text' shows a prompt. -r keeps backslashes as typed (always use it). -s hides typing (passwords). -t 10 gives up after 10 seconds. -n 1 reads one key. With several names, words go to each and the rest to the last. With no name, the line goes to $REPLY.

OptionDoes
-p TEXTshow a prompt
-rraw, keep backslashes
-ssilent, hide input
-t Ntimeout in seconds
-n Nread N characters
-a ARRwords into an array

How to do it (step by step)

  1. Ask a name.
read -rp 'Your city: ' city; echo "Hello from $city"

Output:

Your city: Nashik
Hello from Nashik

What it means: The typed text went into city.

  1. Two values at once.
read -rp 'First Last: ' first last; echo "$last, $first"

Output:

First Last: Sachin Tendulkar
Tendulkar, Sachin

What it means: Words split on spaces.

  1. Hidden password.
read -rsp 'DB password: ' pw; echo; echo "got ${#pw} chars"

Output:

DB password: 
got 9 chars

What it means: Nothing was shown while typing.

  1. Timeout.
read -t 5 -rp 'Continue? ' ans || echo ' no answer, using default'

Output:

Continue?  no answer, using default

What it means: read returns non-zero on timeout.

3. Yes/no confirmation before danger

Why do we need this?

Deleting, restarting or deploying should ask first, so a slip of the finger does not cause an outage.

What is it?

Read one answer, lower-case it, and continue only on y or yes. Treat everything else (including Enter) as no. Allow a -y option (taught below) so automation can skip the question.

How to do it (step by step)

  1. Confirm.
read -rp 'Restart nginx? [y/N] ' a; [[ ${a,,} == y* ]] && echo restarting || echo cancelled

Output:

Restart nginx? [y/N] N
cancelled

What it means: Default is No.

  1. One key.
read -n1 -rp 'Press any key to go on...'; echo

Output:

Press any key to go on...

What it means: Waits for a single key.

  1. Not a terminal?
[ -t 0 ] && echo interactive || echo 'no tty, skip questions'

Output:

interactive

What it means: In cron [ -t 0 ] is false, so do not ask.

4. Positional arguments: $1, $2, $#, $0

Why do we need this?

Arguments let other people and cron run your script without questions: ./deploy.sh shop prod.

What is it?

Words after the script name become $1, $2 ... ${10} (braces from 10). $# is how many there are. $0 is the script name. Arguments with spaces must be quoted by the caller: ./s.sh "my file". Check $# first and stop with a usage message when something is missing.

How to do it (step by step)

  1. See them.
printf '#!/bin/bash\necho "script=$0 count=$# first=$1 second=$2"\n' | tee args.sh && bash args.sh shop prod

Output:

script=args.sh count=2 first=shop second=prod

What it means: Each word got a number.

  1. Quoted argument.
bash args.sh "Pune Camp" east

Output:

script=args.sh count=2 first=Pune Camp second=east

What it means: Quotes kept 'Pune Camp' as one.

  1. Usage check.
bash -c '[ $# -ge 1 ] || { echo "usage: $0 FILE"; exit 2; }; echo ok' myscript

Output:

usage: myscript FILE

What it means: With bash -c the first word after the code becomes $0.

  1. Tenth argument.
set -- a b c d e f g h i j; echo "${10}"

Output:

j

What it means: set -- sets the arguments; ${10} needs braces.

5. "$@" vs "$*" and passing arguments on

Why do we need this?

Wrappers and loops over arguments break on spaces unless you use the right form.

What is it?

"$@" expands to every argument as a separate, quoted word. It is what you want 99% of the time. "$*" joins all arguments into one string with a space (the first char of IFS). Unquoted $@ and $* split on spaces again, so avoid them. To pass all arguments to another command: other_cmd "$@".

FormWith args: 'a b' cGives
"$@"2 words[a b] [c]
"$*"1 word[a b c]
$@3 words[a] [b] [c]

How to do it (step by step)

  1. Loop safely.
set -- 'a b' c; for x in "$@"; do echo "[$x]"; done

Output:

[a b]
[c]

What it means: Each argument kept whole.

  1. Joined.
set -- 'a b' c; echo "[$*]"

Output:

[a b c]

What it means: One string.

  1. A wrapper.
printf '#!/bin/bash\necho "[wrapper] running ls $*"\nexec ls -l "$@"\n' | tee myls.sh && bash myls.sh /etc/hosts

Output:

[wrapper] running ls /etc/hosts
-rw-r--r-- 1 root root 220 Oct 1 /etc/hosts

What it means: $* for the message, "$@" for the command.

6. shift: walk through arguments

Why do we need this?

When the first arguments are special (like a command name) you want to remove them and treat the rest as a list.

What is it?

shift drops $1 and moves every argument one place left, so $2 becomes $1 and $# goes down by one. shift 2 drops two. A common loop is while [ $# -gt 0 ]; do ...; shift; done. Use it for simple long options like --dry-run that getopts cannot handle.

How to do it (step by step)

  1. Basic.
set -- deploy web1 web2; cmd=$1; shift; echo "$cmd on: $*"

Output:

deploy on: web1 web2

What it means: The command is removed from the list.

  1. Loop.
set -- x y z; while [ $# -gt 0 ]; do echo "item $1 (left $#)"; shift; done

Output:

item x (left 3)
item y (left 2)
item z (left 1)

What it means: Each shift moves to the next.

  1. Long options by hand.
set -- --dry-run --env stage app; while [ $# -gt 0 ]; do case $1 in --dry-run) dry=1;; --env) env=$2; shift;; *) break;; esac; shift; done; echo "dry=$dry env=$env rest=$*"

Output:

dry=1 env=stage rest=app

What it means: --env takes a value, so it shifts twice.

7. getopts: proper options like -v and -d DIR

Why do we need this?

Users expect tools to accept -h, -v, -n 5 in any order and combined like -vn 5. getopts does this for you.

What is it?

while getopts 'hvd:' opt; do case $opt in ... esac; done. Each letter is an option; a colon after it (d:) means it needs a value, found in $OPTARG. A leading colon (':hvd:') lets you handle errors yourself: \? for an unknown option and : for a missing value. After the loop, shift $((OPTIND-1)) removes the options so $1 is the first normal argument. getopts only handles short options.

PieceMeaning
'hvd:'options h, v and d with a value
$optthe letter found
$OPTARGvalue of d
$OPTINDindex of the next argument
leading :silent errors you handle

How to do it (step by step)

  1. A script.
cat backup.sh

Output:

#!/bin/bash
verbose=0; dest=/backup
while getopts ':hvd:' opt; do
  case $opt in
    h) echo "usage: $0 [-v] [-d DIR] SRC..."; exit 0;;
    v) verbose=1;;
    d) dest=$OPTARG;;
    :) echo "-$OPTARG needs a value"; exit 2;;
    \?) echo "unknown -$OPTARG"; exit 2;;
  esac
done
shift $((OPTIND-1))
echo "verbose=$verbose dest=$dest sources=$*"

What it means: h and v are flags; d needs a value.

  1. Use it.
./backup.sh -v -d /mnt/usb /etc /home

Output:

verbose=1 dest=/mnt/usb sources=/etc /home

What it means: After shift only the folders remain.

  1. Combined flags.
./backup.sh -vd /srv/bk /var/www

Output:

verbose=1 dest=/srv/bk sources=/var/www

What it means: -vd /srv/bk is the same as -v -d /srv/bk.

  1. Errors.
./backup.sh -x; ./backup.sh -d

Output:

unknown -x
-d needs a value

What it means: Clear messages and exit 2.

8. Usage message and input checks

Why do we need this?

Most bad runs come from wrong input. Check it at the top and explain how to use the script.

What is it?

Write a usage() function that prints the syntax to stderr (>&2) and exits 2. Call it when $# is wrong or -h is given. Check that numbers are numbers ([[ $n =~ ^[0-9]+$ ]]), that files exist ([ -f ]), and that folders are writable ([ -w ]). The if chapter explains these tests.

How to do it (step by step)

  1. Usage function.
usage(){ echo "usage: cleanup.sh DAYS DIR" >&2; exit 2; }; type usage | head -1

Output:

usage is a function

What it means: It prints to stderr and exits.

  1. Number check.
n=abc; [[ $n =~ ^[0-9]+$ ]] && echo number || echo 'not a number'

Output:

not a number

What it means: Regex keeps only digits.

  1. File check.
f=/etc/nope.conf; [ -f "$f" ] || echo "missing $f" >&2

Output:

missing /etc/nope.conf

What it means: Stop before doing anything.

9. Reading from stdin, pipes and files

Why do we need this?

Good tools work in pipes: cat list.txt | ./check.sh. Your script can read lines the same way.

What is it?

If no file is given, read from standard input. while IFS= read -r line; do ...; done reads one line at a time (chapter 5 explains IFS). < file sends a file in. A here-string <<< "text" sends one string. A here-document <

How to do it (step by step)

  1. Pipe in.
printf 'web1\nweb2\n' | while IFS= read -r h; do echo "checking $h"; done

Output:

checking web1
checking web2

What it means: Each line in turn.

  1. Here-string.
read -r a b <<< 'Pune 411001'; echo "$b $a"

Output:

411001 Pune

What it means: One string into read.

  1. Here-document.
cat <<EOF
Host: $(hostname)
User: $USER
EOF

Output:

Host: web01
User: asha

What it means: Variables expanded inside.

  1. File or stdin.
in=${1:-/dev/stdin}; wc -l < "$in"

Output:

3

What it means: /dev/stdin is used when no file is given.

10. Real examples from many industries

Why do we need this?

The same Linux skill shows up in every kind of company. Seeing it in many places helps you remember it.

What is it?

Each row is a made-up team. It shows who uses this and how.

How to do it (step by step)

Team and cityHow they use itCommand
Kiran, school ERP, KolhapurAsk a class name with read -pread -rp 'Class: ' cls
Emma, retail, Dublingetopts in a report toolwhile getopts 'd:o:' o
Wei, fintech, ShanghaiSilent password promptread -rsp 'Pass: ' p
Omar, airline, DohaWrapper passing "$@"exec ansible "$@"
Julia, media, BerlinBatch from a pipecut -d, -f1 ids.csv | ./fetch.sh
Vikram, logistics, ChennaiUsage and exit 2usage(){ ...; exit 2; }

11. Common errors and how to fix them

Why do we need this?

Everyone hits these errors. Knowing the cause saves hours.

What is it?

Read the exact message first. Then match it to a row below.

How to do it (step by step)

Error you seeWhy it happensHow to fix
read hangs in cronNo terminal to type inUse arguments or [ -t 0 ].
[ -t 0 ] || exit 1
Backslashes vanished from inputread without -rUse read -r.
read -r line
$10 printed as first argument plus 0$10 means $1 then 0Use braces.
echo "${10}"
File with spaces split into two argumentsUsed $@ or $* unquotedUse "$@".
for a in "$@"
illegal option -- xUnknown option to getoptsAdd it or handle \?.
getopts ':ab:' o
option requires an argument -- d-d given without a valueGive a value or handle :.
./s.sh -d /tmp
Arguments still include -v after getoptsForgot shift $((OPTIND-1))Shift the options away.
shift $((OPTIND-1))
getopts ignores --longgetopts is short options onlyUse a while/case loop or getopt.
case $1 in --env) ...;; esac
shift count out of rangeshift with no arguments leftCheck $# before shift.
[ $# -gt 0 ] && shift

12. Troubleshooting step by step

Why do we need this?

Print what the script really received.

What is it?

Go top to bottom. Stop at the first step that shows the problem.

How to do it (step by step)

  1. Count.
echo "count=$#"
  1. Each argument.
printf '[%s]\n' "$@"
  1. Option state.
echo "OPTIND=$OPTIND OPTARG=$OPTARG"
  1. Terminal?
[ -t 0 ] && echo tty
  1. Trace parsing.
bash -x s.sh -v -d /tmp x
  1. Hidden characters in input.
printf '%q\n' "$1"

13. Lab 1: A greeting script with read and arguments

Why do we need this?

Write greet.sh that uses $1 if given, otherwise asks with read, and checks the input.

What is it?

A full hands-on lab. Run every step on a test Linux machine (an EC2 instance, a VM, or WSL).

How to do it (step by step)

  1. Folder.
mkdir -p ~/lab39 && cd ~/lab39
  1. Write.
printf '#!/bin/bash\nname=${1:-}\nif [ -z "$name" ]; then read -rp "Name: " name; fi\n[ -n "$name" ] || { echo "name required" >&2; exit 2; }\necho "Namaskar, $name!"\n' | tee greet.sh && chmod +x greet.sh
  1. With an argument.
./greet.sh Meera

Output:

Namaskar, Meera!
  1. Without.
./greet.sh

Output:

Name: Raj
Namaskar, Raj!
  1. Empty input.
./greet.sh <<< ''; echo $?

Output:

name required
2
  1. From a pipe.
echo Sara | ./greet.sh

Output:

Namaskar, Sara!

14. Lab 2: A real getopts tool

Why do we need this?

Build findbig.sh with -n COUNT, -d DIR and -h, which lists the largest files.

What is it?

A full hands-on lab. Run every step on a test Linux machine (an EC2 instance, a VM, or WSL).

How to do it (step by step)

  1. Write the parser.
printf '#!/bin/bash\nn=5; d=.\nwhile getopts ":hn:d:" o; do case $o in h) echo "usage: $0 [-n N] [-d DIR]"; exit 0;; n) n=$OPTARG;; d) d=$OPTARG;; :) echo "-$OPTARG needs value" >&2; exit 2;; \\?) echo "bad -$OPTARG" >&2; exit 2;; esac; done\nshift $((OPTIND-1))\n[[ $n =~ ^[0-9]+$ ]] || { echo "N must be a number" >&2; exit 2; }\ndu -ah "$d" 2>/dev/null | sort -rh | head -n "$n"\n' | tee findbig.sh && chmod +x findbig.sh
  1. Help.
./findbig.sh -h

Output:

usage: ./findbig.sh [-n N] [-d DIR]
  1. Default.
./findbig.sh -d /var/log | head -2

Output:

1.2G /var/log
800M /var/log/journal
  1. Three in /etc.
./findbig.sh -n 3 -d /etc

Output:

6.1M /etc
3.0M /etc/selinux
1.1M /etc/ssl
  1. Bad number.
./findbig.sh -n many; echo $?

Output:

N must be a number
2
  1. Missing value.
./findbig.sh -d

Output:

-d needs value

Ravindra Bagale's Tip

Always quote "$@" when you pass arguments on, and always end a getopts loop with shift $((OPTIND-1)). These two lines are where most argument bugs hide.

15. Frequently asked questions

Q. read or arguments?

Arguments for automation, read for people.

Q. Why read -r?

Keeps backslashes.

Q. Long options with getopts?

Not supported; use a case loop or GNU getopt.

Q. What is OPTIND?

Index of the next argument to process.

Q. Why exit 2 for bad usage?

Convention for misuse.

Q. Where should usage go?

To stderr with >&2.

Q. Can I read a password from a file?

Yes; read -r pw < file with chmod 600.

Q. What is $REPLY?

Default variable of read.

16. Interview questions and answers

Beginner level

Q. First argument?

$1.

Q. Number of arguments?

$#.

Q. Prompt the user?

read -p.

Q. Hide a password?

read -s.

Mid level level

Q. "$@" vs "$*"?

Separate words vs one string.

Q. What does shift do?

Drops $1 and moves the rest.

Q. getopts value for -d?

d: in the spec, value in $OPTARG.

Q. Why shift $((OPTIND-1))?

To leave only non-option args.

Senior level

Q. Design CLI for a deploy script?

getopts for flags, positional for targets, usage, validation, -y to skip prompts.

Q. Script must work in pipes and with files?

Read from "${1:-/dev/stdin}".

Q. Silent vs normal getopts errors?

Leading colon: you handle \? and :.

Q. Safely accept secrets?

Env var or file, not argument (visible in ps).

Try at home

  1. Write add.sh that adds all numbers given as arguments and prints the total. Reject anything that is not a number.
  2. Add -q (quiet) and -h (help) options to it with getopts.

Practice Tasks

About this scenario

London Legal LLP is a law business in London. Oliver Hughes looks after its IT and cloud work. They count money in GBP and run their AWS resources in the eu-west-2 Region. In the tasks below you do real jobs for them using what this lesson teaches. All names, account IDs, IP addresses and numbers are made up for practice.

0 / 21

Easy Ask for a name

Why: BIZ tools must take options like real commands.

What to do: Ask "Branch: " and store the answer in br, keeping backslashes.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Easy How many

Why: BIZ tools must take options like real commands.

What to do: Print how many arguments the script got.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Easy First argument

Why: BIZ tools must take options like real commands.

What to do: Print the first argument in quotes.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Easy Script name

Why: BIZ tools must take options like real commands.

What to do: Print the name the script was called with.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Easy Drop three

Why: BIZ tools must take options like real commands.

What to do: Drop the first three arguments.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Easy Option value

Why: BIZ tools must take options like real commands.

What to do: Store the current option value into outdir.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Medium Hidden PIN

Why: BIZ tools must take options like real commands.

What to do: Read a hidden value into pin with the prompt "PIN: ".

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Medium Timeout

Why: BIZ tools must take options like real commands.

What to do: Read into ans with a 15 second timeout, raw mode.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Medium One key

Why: BIZ tools must take options like real commands.

What to do: Read exactly one character into key.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Medium Eleventh

Why: BIZ tools must take options like real commands.

What to do: Print the eleventh argument.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Medium Each argument on a line

Why: BIZ tools must take options like real commands.

What to do: Print every argument on its own line with printf, keeping spaces.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Medium Set arguments

Why: BIZ tools must take options like real commands.

What to do: Set the arguments to alpha beta gamma.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Medium getopts spec

Why: BIZ tools must take options like real commands.

What to do: Start a getopts loop for flags q and f, where f needs a value, storing the letter in o.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Medium Remove options

Why: BIZ tools must take options like real commands.

What to do: Remove all parsed options after the getopts loop.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Medium Output to terminal?

Why: BIZ tools must take options like real commands.

What to do: Test whether standard output is a terminal and print term if it is.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Medium Here-string

Why: BIZ tools must take options like real commands.

What to do: Read "Satara 415001" into the variables town and code with a here-string.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Medium Pass on

Why: BIZ tools must take options like real commands.

What to do: Run rsync passing all of the script arguments safely.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Hard Words into array

Why: BIZ tools must take options like real commands.

What to do: Read one line into the array words, raw mode.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Hard Silent getopts

Why: BIZ tools must take options like real commands.

What to do: Start a silent-error getopts loop for h and n with a value, letter in opt.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Hard File or stdin

Why: BIZ tools must take options like real commands.

What to do: Set src to the first argument, or /dev/stdin if none.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Hard Is a number

Why: BIZ tools must take options like real commands.

What to do: Test with [[ ]] that the variable qty is only digits and print ok.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

In short

  1. read -rp asks; -s hides; -t times out.
  2. $1..$9, ${10}, $# and $0 hold arguments.
  3. Pass arguments on with "$@".
  4. shift moves through arguments.
  5. getopts 'hvd:' with $OPTARG, then shift $((OPTIND-1)).
  6. Validate input and print usage to stderr with exit 2.

Revision, comparison and interview cards

Revise this lesson in a few minutes. Save the cards on your phone or download them as PNG files. The QR code on each card opens this lesson.

Script arguments. $1, $2 = first, second. $# = how many. "$@" = all, safely. Drop the first.
Revision card: Script arguments · Download PNG · Open card page
getopts in 4 steps. List flags; colon = needs value. Loop with while. case on the letter. Value is in OPTARG.
Revision card: getopts in 4 steps · Download PNG · Open card page
arguments vs read. Given on the command line. / Typed while running.
Comparison: arguments vs read · Download PNG · Open card page
getopts vs while/case. Built in, short flags. / Hand-written loop.
Comparison: getopts vs while/case · Download PNG · Open card page
"$@" vs "$*"?. "$@" keeps each argument separate. "$*" joins them into one. Use "$@" almost always.
Interview card: "$@" vs "$*"? · Download PNG · Open card page
Missing arguments?. Check $# first. Print usage to stderr. Exit with code 2.
Interview card: Missing arguments? · Download PNG · Open card page
Read a password safely?. read -s hides typing. -p shows a prompt. Example.
Interview card: Read a password safely? · Download PNG · Open card page
getopts vs manual parsing?. getopts: short flags, built in. Manual case loop for long --flags. Shift after getopts.
Interview card: getopts vs manual parsing? · Download PNG · Open card page

More cards: Ravi Sir's Cards.