DEV Community

Cover image for Special Bash Parameters
Seun Agbede
Seun Agbede

Posted on

Special Bash Parameters

It's always amazing observing experts. It often leaves you inspired, motivated and hungry for more professional growth of your own. Recently, I switched teams and now work alongside someone who has been writing bash scripts professionally for longer than I have been alive. Watching him approach problems has left me in awe.

This week, I learnt about built-in bash parameters from him and thought to explore them a little more.

NB: The shell treats these parameters specially. They can only be referenced. Assignment to them is not allowed.

Parameters explored


1. Asterisk *

Variable Usage
$* Stores all the arguments that were entered on the command line ($1 $2 ...)

For example take script foo.sh below

#!/bin/bash

# loops over arguments and prints them in a new line

for i in $* ; do
  echo -e "$i\n" 
done
Enter fullscreen mode Exit fullscreen mode

Now run the script and pass a few arguments

$ ./foo.sh arg-1 arg-2 arg-3 arg-4
arg-1

arg-2

arg-3

arg-4


# notice double quotes around "arg-2 arg-3" are ignored 
# they are treated as 2 seperate arguments

$ ./foo.sh arg-1 "arg-2 arg-3" arg-4
arg-1

arg-2

arg-3

arg-4
Enter fullscreen mode Exit fullscreen mode

However, when we place $* in double quotes "$*" all the arguments are taken as a single string

#!/bin/bash

#notice the change with "$*"

for i in "$*" ; do
  echo -e "$i\n" 
done
Enter fullscreen mode Exit fullscreen mode
$ ./foo.sh arg-1 arg-2 arg-3 arg-4
arg-1 arg-2 arg-3 arg-4
Enter fullscreen mode Exit fullscreen mode


2. At sign @

Variable Usage
$@ Stores all the arguments that were entered on the command line, individually quoted ("$1" "$2" ...)

$@ is similar to $* but with a subtle difference.

#!/bin/bash

for i in $@ ; do
  echo -e "$i\n" 
done
Enter fullscreen mode Exit fullscreen mode
$ ./foo.sh arg-1 arg-2 arg-3 arg-4
arg-1

arg-2

arg-3

arg-4


# same behaviour as $*
# double quotes are ignored

$ ./foo.sh arg-1 "arg-2 arg-3" arg-4
arg-1

arg-2

arg-3

arg-4
Enter fullscreen mode Exit fullscreen mode

However, $@ behaviour changes when in double quotes "$@"

#!/bin/bash

#notice the change with "$@"

for i in "$@" ; do
  echo -e "$i\n" 
done
Enter fullscreen mode Exit fullscreen mode

# double quotes are treated as a single argument
$ ./foo.sh arg-1 "arg-2 arg-3" arg-4
arg-1 

arg-2 arg-3 

arg-4
Enter fullscreen mode Exit fullscreen mode

With "$@", all the arguments that were entered are treated individually quoted ("$1" "$2"...)

This is generally the behaviour we often want when writing scripts and how it differs from $*


3. Hashtag #

Variable Usage
$# Stores the number of command-line arguments that were passed to the shell program.

Take foo.sh

#!/bin/bash

echo "Number of arguments entered is : $# "
Enter fullscreen mode Exit fullscreen mode
$ ./foo.sh arg-1 arg-2 arg-3 arg-4
Number of arguments entered is : 4


$ ./foo.sh arg-1 arg-2 
Number of arguments entered is : 2
Enter fullscreen mode Exit fullscreen mode


4. Question mark ?

Variable Usage
$? Stores the exit value of the last command that was executed.

It's also called exit status and this variable stores the exit value of the last command that was executed. It is an integer number.

If $? equals 0, the previously run command was successful.
If $? is between 1-255, the command failed.
If $? equals 127, then the command is not found.

Example usage :

$ echo "Hello there!" > file.txt

$ cat file.txt
Hello there!

$ echo $?
0

# returns 0 as the last run command was successful.
Enter fullscreen mode Exit fullscreen mode
$ cat non-existent-file.txt
cat: non-existent-file.txt: No such file or directory

$ echo $?
1

# returns 1 as the last run command was unsuccessful.
Enter fullscreen mode Exit fullscreen mode

You can see the usefullness of $? in this urlchecker script bar.sh

#!/bin/bash

curl --output /dev/null --silent ${1} && exit_code=$? || exit_code=$?

    if [ ${exit_code} -eq 0 ]; then
        echo "${1} is a valid url"
    else
        echo "Sorry, ${1} is NOT a valid url"
    fi
Enter fullscreen mode Exit fullscreen mode

Invoking the script and passing in both valid and invalid urls

$ ./bar.sh https://www.google.com
https://www.google.com is a valid url

$ ./bar.sh https://www.not-a-valid-website.com
Sorry, https://www.not-a-valid-website.com is NOT a valid url
Enter fullscreen mode Exit fullscreen mode


5. Zero 0

Variable Usage
$0 Stores the name of the script that is currently being executed.

Take script bar.sh

#!/bin/bash

echo "This is the name of this shell script : $0"
Enter fullscreen mode Exit fullscreen mode
$ ./bar.sh
This is the name of this shell script : ./bar.sh
Enter fullscreen mode Exit fullscreen mode

Just running in the terminal, you get :

$ echo $0
-bash
Enter fullscreen mode Exit fullscreen mode

In essense, $0 holds the name of the currently executing script in bash.

You can see more on special bash parameters from the Bash reference manual

Top comments (0)