3. Variables and constants
-
Variables in bash don't have to be declared, we just use them:
foo="yes"
echo $foo
We have a shell expansion here, and it is the same as:
echo yes
echo $foo1
It is the first time that the shell sees the variable
foo1
, however it does not complain but just creates it and gives it an empty value. This means that we should be careful with spelling the names of the variables, otherwise we may get strange results.touch foo.txt
foo=foo.txt
foo1=foo1.txt
cp $foo $fool
We have misspelled the second argument, so shell expands it to an empty string and we get an error from
cp
. -
To denote constants in bash, we use uppercase variable names, by convention:
vim sys_info.sh
:% s/$title/$TITLE/g
:% s/title=/TITLE=/
:/^TITLE=/ s/Report/Report for $HOSTNAME/
:wq
./sys_info.sh
We have also used the environment variable
HOSTNAME
. Environment variables are considered as constants, so they are in uppercase.Actually, there is a way to make sure that a variable cannot be changed (is a constant), although it is not used frequently:
sed -i sys_info.sh -e 's/TITLE=/declare -r TITLE=/'
cat sys_info.sh
highlight -O xterm256 sys_info.sh
./sys_info.sh
The option
-r
ofdeclare
means "read-only". So, we cannot assign a value again to this variable. -
When a value is assigned to a variable there should be no spaces around the equal sign:
a=z
echo $a
Shell expansions are applied to the value, before assignment:
b="a string"
c="a string and $b"
echo $c
d=$(ls -l foo.txt)
echo $d
e=$((5 * 7))
echo $e
f="\t\ta string\n"
echo $f
echo -e $f
help echo
Multiple assignments may be done on a single line:
a=5 b="a string"
echo $a $b
-
During expansion, variable names may be surrounded by curly braces
{}
, which are necessary in some cases. For example:filename="myfile"
touch $filename
mv $filename $filename1
What we want is to rename the file to
myfile1
, but the shell is interpretingfilename1
as a variable, which of course has not been assigned yet and is empty. We should do it like thismv $filename ${filename}1
ls -l myfile1
-
Let's add a timestamp to the report, using variables/constants:
date +"%x %r %Z"
echo $USER
vim sys_info.sh
/TITLE=
Type
o
and enter below:CURRENT_TIME=$(date +"%x %r %Z")
TIMESTAMP="Generated on $CURRENT_TIME, by $USER"Press ESC and then
:w
to save./<h1>
Type
Yp
to copy and paste the current line.:s/h1/p/g
:s/TITLE/TIMESTAMP/
:wq
./sys_info.sh
The script so far should look like this:
#!/bin/bash
# Program to output a system information page.
declare -r TITLE="System Information Report for $HOSTNAME"
CURRENT_TIME=$(date +"%x %r %Z")
TIMESTAMP="Generated on $CURRENT_TIME, by $USER"
echo "<html>
<head>
<title>$TITLE</title>
</head>
<body>
<h1>$TITLE</h1>
<p>$TIMESTAMP</p>
</body>
</html>"
The output of the script should look like this:
<html>
<head>
<title>System Information Report for linuxmint</title>
</head>
<body>
<h1>System Information Report for linuxmint</h1>
<p>Generated on 09/28/23 07:21:03 AM UTC, by dashamir</p>
</body>
</html>