chmod u+x script.sh
Shabang makes sure that the script is executed using the right shell, no matter which shell the user uses to execute the script file.
We can add some arguments to the shell:
#!/bin/bash -v - will print each script line before executing it. It’s useful
for debugging when script suddenly stops at some point and hangs. Also shows
#!/bin/bash -x - like above, but it will also show variables values. Doesn’t
It’s a good idea to include the following line in the beginning of the script. It will stop execution in case of errors:
It’s a shorthand of:
Only use letters, numbers, and underscores. First character cannot be a number.
It’s recommended not to use upper-case names, becasue all default variables are upper-case.
Variable names ae case-sensitive. There can’t be spaces around the
=. If the
value has spaces, it needs to be in
Shell will replace the $variable with its value before executing the command. If the variable does not exist, an empty string will be used.
Variable can contain a command and can be executed (can be dangerous!):
The above removes
Variables are available only in the process where they were defined. To change
export can be used:
Now, if I run some script from this shell, the
myVar variable will be
When invoking a script, user might pass some arguments. These are available via
$2, and so on.
It is a good idea to create new variables at the beginning of the script with the argments, so that it is easier to understand what they contain.
If our variables may contain spaces, it is a good idea to usethe varibale with
"". That way, commands will “understand” that the space is not for a separate
command, but rather a part of filename.
Multiple variables can be put in one pair of
"", as can be seen above Before
execution of a given line, the variables are substituted with actual values. If
container had spaces in it, it is OK, becasue there are
There is a utility shellcheck (command-line and shellcheck.net) that shows
issues in script files, i.e. missing
ZSH does not require
"", because it does not split words from variables as
separate commands. It kind of automatically interprets variables as if they were
Single quotes are used to escape the
End of Options
When passing arguments to scripts, someone could use
-. Often, that would be a
problem, it could be interpreted as some command option. Example:
Running this script with
./script.sh -p will not create a directory
will be taken as an option of
There is a special “end of options” string:
Whatever is in
$1, it will be interpreted as an argument, and not an option.
Not all commands understand
echo). That’s why it is a good idea to
printf instead when the printed value is not granted to be safe:
It might happen that we need to construct a string containing the variable, like this:
Only $v2 will be printed, becasue the shell will look for variable
In this case
_ was a problem, because
_ is a valid character in a variable
name. The issue would not be there if there was A
/, or any other
character that is not valid in a variable name.
declare allows for more advances variables creation. It allows to set a type
of varable (default is always string), and others.
UNIX programs can return values in range 0-255. 0 is success, any other code is an error. There may be many kinds of errors, so different values can be returned.
exit 0 - success
exit 1 - error
These check the return value (exit code) of a
testcode and act based on it
else is optional.
[[ $var ]] - check if
var has any value
[[ $var = "ok" ]] - check if
var equals “ok” (SPACES AROUND
[[ -e file1 ]] - check if a file
[[ -d dir1 ]] - check if a directory
[[ ! testcode ]] - NOT (i.e.,
[[ ! -e file1 ]] is TRUE when
[[ testcode1 && testcode2 ]] - AND
[[ testcode1 || testcode2 ]] - OR
[[, and spaces before