Intermediate Bash
Author(s): Matthias Lee (ml2322)
Last Updated: 07-07-2025
Recommended Prerequisites (click to expand)
Now that you understand the basics of Bash, we can learn about some more advanced things it can do.
Privilege escalation
In linux, the hidden root user has special privileges. The root user can, for the most part, read, write, and change permissions on
every file. Many commands can only be executed as root, since they use these more locked down files.
As mentioned, some commands require root privileges to run, as they modify restricted system files or interact with the system in a privileged manner. To run
commands as root, you can prefix them with sudo. Sudo is another command that runs whatever you specified with root privileges. A common command that needs
root access is apt for installing, removing, or modifying programs on your system.
user@system:/home/user$ ls /root
Permission Denied
user@system:/home/user$ sudo ls /root
1984.pdf
user@system:/home/user$ whoami
user
user@system:/home/user$ sudo whoami
root
Scripts
Bash isn't just for interacting with the terminal, you can script in it too. To make a bash script, put bash commands (as you would run them in the
terminal) in a file with the .sh or .bash extension. While not usually required, it's good practice to put #!/usr/bin/bash at the top of the file, as it
is required in some cases. To run a script, just run bash <script>, and bash will execute your script.
Variables
Just like any other programming language, Bash has variables too, which you can read, create, and modify.
Setting variables
To set a variable in bash, you can either run variable=value, or export variable=value. The key difference between the two is that if you use export, any
programs you run within bash can access the variable too. NOTE: one quirk of bash is that you can not have a space before or after the =.
Using variables
To use a variable, you can do $<name>, where <name> is the variable you want to access. That will then get substituted out for the variable's value. For
example, if variable foo is set to bar, echo $foo will print bar. This syntax works, but has limitations, as you can not put regular characters straight
after the variable. For example, ($variablehello) will be interpreted as you trying to access a variable called variablehello, instead of accessing variable
and taking hello as additional input right after. To solve this, you can use the following syntax instead: ${variable}. This will also access the variable,
variable, except bash knows when it ends by the curly braces. This syntax also has other uses we'll discuss later. Uniquely, if the variable doesn't exist,
bash doesn't throw an error, it just treats it like the variable is blank
Examples
user@system:/home/user$ var=a
user@system:/home/user$ echo $var
a
user@system:/home/user$ export env_var=b
user@system:/user/user$ echo $env_var
b
user@system:/user/user$ some_command
(this command can access env_var but not var)
user@system:/user/user$ echo $varbc
(no output because varbc doesn't exist)
user@system:/user/user$ echo ${var}bc
abc
Joining Commands
Bash has three main ways to let you run several commands at once:
;
Joining commands with a semicolon will make them run sequentially, no matter if they succeed or not.
&&
Joining commands with && will execute the second command only if the first succeeds
||
Joining commands with || will execute the second command only if the first fails
user@system:/home/user$ command_a; command_b
(both will always run)
user@system:/home/user$ command_a && command_b
(b will run only if a succeeds)
user@system:/home/user$ command_a || command_b
(b will run only if a fails)