Inside a shell script, which special parameter expands to the number of positional parameters the script was given?

LPIC-1 Exam 102-500, objective 105. Shells and shell scripting easy

Draft — not checked yet. This question was written from the published exam objectives and cites the clause it comes from, but nobody has yet read it against that clause and signed for it.

It is kept out of search results and out of mock exams until they have. Read the source below before you take the answer as settled.

The options

Not correct $@

Wrong. $@ expands to the positional parameters themselves. Quoted as "$@" it produces one word per argument.

Not correct $0

Wrong. $0 is the name the script was invoked as. It is deliberately not counted in $#.

Not correct $?

Wrong. $? is the exit status of the last completed foreground command, which has nothing to do with argument count.

Correct $#

Correct. $# is the count of positional parameters, excluding $0. It is the usual way to validate usage, for example `[ $# -ne 2 ] && exit 1`.

Why

Positional parameters are $1 through $9, then ${10} and beyond with braces. $# counts them, $@ and $* expand them, and `shift` drops $1 and renumbers the rest, decreasing $# by one. $0 is not a positional parameter, so a script called with two arguments reports $# as 2.

Where this comes from

Cited
LPI exam objective 105.2
What it says
Use command line arguments passed to a script.

Practise this

Reading one question is not practice. The trainer will draw a set from objective 105 and space the ones you get wrong.

Practise LPIC-1 Exam 102-500