This page has been tested on macOS Catalina and Ubuntu 18.04 & 20.04
Assign a value to a variable using a single equals sign and no spaces, then use the echo
function to display the value of the variable. When you do the call, you need to prepend a dollar sign; that’s Bash/Zsh’s way of knowing you’re using a variable:
message=Hello
echo $message
Hello
If you want to have a space in your value, use quotation marks (double or single):
# Single quotation marks
message='Hello, World'
echo $message
# Double quotation marks
message="Hello, World"
echo $message
Hello, World
Hello, World
So it doesn’t matter if you use double or single quotation marks when you assign a value to a variable, but it does make a difference when you call that variable:
message='Hello
World'
echo My message is: $message # No quotation marks
echo 'My message is: $message' # Single quotation marks
echo "My message is: $message" # Double quotation marks
My message is: Hello World
My message is: $message
My message is: Hello
World
Another example using the touch
command (which creates a new file):
new_file="My File.txt"
touch $new_file
touch "$new_file"
The first touch
command will create two new files (“My” and “File.txt”) whereas the second will only create one (“My File.txt”). This is why, in general, it is always a good idea to use double quotation marks around your variable calls. If you are creating, importing or deleting files you always want to make sure you’re referring to the correct ones!
Note that $message
is actually shorthand for ${message}
: a dollar sign AND curly brackets are used to tell Bash/Zsh what the name of your variable is, but, if you leave out the brackets then Bash/Zsh can usually still guess correctly. However, this is not the case if you want your variable to appear in the middle of a string:
prefix='un'
# This does not work as expected
echo "That's $prefixbelievable"
# This works as expected
echo "That's ${prefix}believable"
That's
That's unbelievable
So, if you always want to be 100% accurate, it’s good practice to always use both double quotation marks and curly brackets, "${like_this}"
.
The ‘hash’, ‘at’ and ‘question mark’ symbols are all pre-defined variables in Bash/Zsh.
$#
returns the number of arguments that were parsed to a script$@
returns the arguments themselves$?
returns the exit code of a process
If a script called “myscript.sh” contained the following:
# Number of arguments
echo $#
# The arguments
echo $@
# Exit code
echo $?
And it was run from the terminal with bash myscript.sh Hello World
it would produce the following:
2
Hello World
0
Unlike most programming languages, Bash/Zsh doesn’t worry too much about what type a particular variable is. If you want to treat a variable as a word you can, and if it contains only numbers and you want to treat it as a number you also can:
variable="1234"
# Treat it as a string
echo "My variable is $variable"
# Treat it as a number
let "variable += 1111"
echo "My variable is $variable"
My variable is 1234
My variable is 2345
This also works for nulls (empty variables) and undeclared variables:
# Undeclared variables don't pose a problem
echo "There is nothing here: $variable"
variable=""
# Treat it as a string
echo "There is nothing here: $variable"
# Treat it as a number
let "variable += 1"
echo "Now there is something here: $variable"
There is nothing here:
There is nothing here:
Now there is something here: 1
The last variable type to worry about is arrays. Very simply, they are lists of items and are created by using round brackets. At this point, if we try to do anything with an array we can only use the first number; we have to use a loop if we want to do anything else and those are discussed on another page.
# Create an array
x=(10 11 12 13)
# Multiply by 2
y=$(expr $x \* 2)
# Unfortunately, this only works on the first element (which is the number 10)
echo $y
20