What the $!$*$@ … Bash Shell Variables

There’s nothing complex about Bash shell variables, but they’re also not something you’d likely memorize. Frankly, they’re just not that interesting. ๐Ÿ˜‰

So I wrote a script to demonstrate how they work. For me, it’s just easier to decipher what the variables do using a simple example.

Notice I’ve passed only 2 arguments. Look carefully at the quotes, which in total include up 3 words.

$ ./shell-special-params.sh “I love” “handsonkeyboard.com”
$*: I love handsonkeyboard.com
$@: I love handsonkeyboard.com
$#: 2
$?: 0
$-: hB
$$: 18414
$!: 18416
$0: ./shell-special-params.sh
$_: $0: ./shell-special-params.sh

$*This parameter represents all arguments passed to the script, separated using the first character of the special shell variable IFS — the internal field separator.
$@This parameter represents all arguments passed to the script separated as words.
$#The number of arguments passed to the script.
$?The exit status of the most recently executed foreground pipeline.
$-The shell’s current option flags, which are:

H – histexpand
m – monitor
h – hashall
B – braceexpand
i – interactive

For more information on option flags, this is the best source I could find on the topic.
$$The process ID of the shell.
$!The process ID of the most recently executed background command.
$0The name of the shell script.
$_This is from the Linux Documentation Project’s article on linux-variables:
“The underscore variable is set at shell startup and contains the absolute file name of the shell or script being executed as passed in the argument list. Subsequently, it expands to the last argument to the previous command, after expansion. It is also set to the full pathname of each command executed and placed in the environment exported to that command. When checking mail, this parameter holds the name of the mail file.”

The script used in the above output:

# the following command is executed to get a process ID for $!
seq 1000000 | sort -nr > /dev/null &
echo “\$*: $*”
echo “\$@: $@”
echo “\$#: $#”
echo “\$?: $?”
echo “\$-: $-“
echo “\$\$: $$”
echo “\$!: $!”
echo “\$0: $0”
echo “\$_: $_”