GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Ubuntu Wiki
  • Search
  • Log in
  • Editing guide
  • Recent changes
  • New pages
  • Random page
  • Special pages
  • Quality issues
  • Report bugs
  • Page
  • What links here
  • Related changes
  • Beginning

This view

  • Original page
  • New address

GeezerVison is showing wiki.ubuntu.com — Bash scripting for beginners - Ubuntu Wiki

(Redirected from Beginners/BashScripting)

This guide begins with useful terminal commands before introducing the basics of scripting with Bash.

Note
This guide was migrated from the tutorial "Beginners/BashScripting" on the old Ubuntu community wiki. It has been refined and updated to reflect current best practices.

Tidying

This page has been identified as needing tidying and should be reviewed for clarity, structure, and formatting.

Commands

During your time as an Ubuntu user, you will use the terminal to perform various tasks. In this article, we'll discuss the following topics:

  • Text editors
  • Absolute and relative file paths
  • Creating directories
  • Deleting files
  • Deleting directories and their sub-directories
  • Opening applications as root
  • Backing up your files
  • Backing up your directories
  • Checking system performance
  • Checking Devices
  • Checking wireless connection

Text editors

There are several editors available in Ubuntu. The most common ones are Nano and Vim. Running them is as simple as invoking them in the terminal.

nano
vim

Nano is probably the easiest to use for absolute beginners. If one is inclined to learn Vim, check out the Vim Tutor that is builtin to Vim. It can be run by invoking the following command:

vimtutor

Absolute and relative file paths

Note

The words "folder" and "directory" mean the same thing and are often used interchangeably. The canonical term is technically "directory", as that is what is used in Unix/Linux manual pages and documentation, but directories can be thought of as folders metaphorically.

An absolute path to a file or directory is the full path starting from the root directory. The following are examples of absolute paths:

/home/ubuntu
/home/ubuntu/.bashrc
/var/log/messages
/usr/local/bin
/bin/vim

A relative path to a file or directory is the path starting from the current working directory; that is, relative to the current working directory. The following are examples of a relative path where we'll assume the current working directory is /home/ubuntu:

Downloads/
.bashrc
Pictures/photo.jpg
.config/autostart
.local/share/applications/

For example, suppose the current working directory is /home/ubuntu/Downloads, and we want to use Vim to open /home/ubuntu/.bashrc :

vim ../.bashrc
  • ../ is shorthand for the parent directory, which is /home/ubuntu in this case.
  • ../../ is shorthand for the parent of the parent (grandparent) directory, which is /home in this case.
  • ../../../ is shorthand for the parent of the parent of the parent (great-grandparent) directory, which is / in this case.
  • The ../ syntax can go to as many levels as exist relative to the current working directory in the filesystem.

If an absolute path is not specified, Bash assumes the path is relative. For example, if the current working directory is /home/ubuntu, the following command will open /home/ubuntu/Templates/file.txt in Nano:

nano Templates/file.txt

Creating directories

On Desktop, directories can be created by right clicking in the Nautilus file manager and selecting 'New Folder'. This can also be done with a keyboard shortcut: SHIFT + CTRL + N. To do the same from the terminal, run:

mkdir /home/ubuntu/Desktop/new_directory

The mkdir (make directory) command creates a directory at the specified path.

To create directories recursively, use mkdir -p. The -p flag tells the command to create any parent directories to the specified path. For example, if you want to create a subdirectory and ensure its parent directory is created as well, you can use something like the following:

mkdir -p ~/files/work/project

This ensures that if ~/files and ~/files/work do not exist, they are created when creating the project subdirectory.

For more information on the usage of the mkdir command, see mkdir(1), or run man mkdir in the terminal.

Deleting files and directories

Deleting files are done with the rm (remove) command:

rm /home/ubuntu/file_to_be_deleted

To remove a directory and all its contents recursively:

Warning

The -r (recursive) flag can result in unintended data loss if used carelessly.
rm -r /home/ubuntu/unneeded_directory

You can also use the -f flag to force remove the directory, but most of the time this is not necessary.

rm -rf /home/ubuntu/unneeded_directory

Warning

The following commands will result in a broken system because the recursive -r flag and the force -f flag will forcibly remove the root directory and all its contents. These commands should never be run on a typical workstation or server.
rm -rf /*
rm -rf /

For more information on the usage of the rm command, see rm(1), or run man rm in the terminal.

Running commands as root

When working on the command line, you usually want to work with the default permissions. This way you ensure that you won't accidentally break anything belonging to the system or other users, so long as the system and other users haven't altered their file permissions.

There will be times when you wish to copy a file to a system directory like /usr/local/bin to make it available to all users of the system. Only the system administrator (i.e. the user 'root') should have permission to alter the contents of system directories. If you try to copy a file to /usr/local/bin as a non-root user, it will result in a "permission denied" error.

cp Downloads/script.sh /usr/local/bin/
cp: cannot create regular file '/usr/local/bin/script.sh': Permission denied

For more information on the usage of the cp command, see cp(1), or run man cp in the terminal.

As it would be tedious to always login as root to do administrative tasks, you can use sudo to execute a single command with root privileges.

Note

It's considered good practice to avoid logging in and performing tasks as the root user. Instead, use the sudo command as a normal user to execute commands with root privileges.
sudo cp Downloads/script.sh /usr/local/bin/

The default Ubuntu installation is configured so that the user who was created during system installation is allowed to use the sudo command. It will prompt for the password and execute the command as the root user.

For more information on the usage of the sudo command, see sudo(8), or run man sudo in the terminal.

Opening GUI applications as root

Sometimes you will want to edit a config file in your root directory, in order to save changes to this file you need root privileges, so you need to open a text editor as root. All you will need is just sudo:

sudo gedit

Backing up your files

To create a backup of a file, you can use the cp (copy) command:

cp source_file dest_file

This will copy the source file to the destination file.

Using the previous example, if you want to backup your bashrc file, try the following command:

Note

The ~/ syntax is shorthand for the absolute path to the user's home directory, /home/ubuntu.
sudo cp ~/.bashrc ~/.bashrc.backup

Suppose you downloaded a GIF titled dancing_hotdog.gif in your web browser, and it was saved to the Downloads directory. If you want to copy the file to the Pictures directory, you would execute the following command:

cp ~/Downloads/dancing_hotdog.gif ~/Pictures/

Warning

The destination directory, ~/Pictures, must exist for the copy to succeed. Otherwise you'll get an error: cp: 'Pictures/' is not a directory

Backing up directories

To backup one directory to another, use cp -r (recursive):

cp -r /home/ubuntu/source_directory /home/ubuntu/backup_directory

If you want to copy all of the contents of your /home/ubuntu/source_directory directory to the /home/ubuntu/backup_directory:

cp -r /home/ubuntu/source_directory/ /home/ubuntu/backup_directory

Command reference

For a full command reference, refer to the terminal command reference page.

Scripting

Tip

The commands given in the scripting section are to be put into the text editor and not in the terminal unless instructed otherwise.

Bash is also a scripting language. You can create a bash script by opening your favorite text editor to edit your script and then saving it. Typically a script is saved with a .sh file extension, but is not necessary. We'll start off with the proverbial "Hello, World".

#!/usr/bin/env bash         

echo "Hello, World"

The first line of the script is called the shebang (#!) line, which tells the Linux kernel to treat the file as input to the Bash interpreter.

Note

It's considered a best practice to use /usr/bin/env bash for the shebang line when writing bash scripts. The reason is because not every Unix-like system has the bash binary available at the /bin/bash path, so the env command instructs the kernel to look for the bash binary in $PATH and use the first occurrence it finds. However, in most Linux systems it is located at /bin/bash.

To run a bash script, you first have to have the correct file permissions. We do this with chmod:

chmod a+x hello_world.sh   # Gives everyone (owner, group, and other) execute permissions
chmod 700 hello_world.sh   # Gives read, write, execute permissions only to the owner (the ubuntu user, in our case)

These permissions allow us the execute the script as a binary.

Next, open a terminal and run the script like this:

./hello_world.sh

This should print "Hello, World" to the console.

Variables

Variables store information (values) that can be used later in the script. To define a variable named var with the value FOO, use the following syntax:

var="FOO"

The name of the variable (in this case, var) can be anything you want, as long as it doesn't begin with a number. To access the variable's contents, you need to put a $ in front of it like this:

echo "$var"

When accessing the contents of the variable, we usually say we are expanding the variable. It is good practice to use double quotes around a variable when expanding it in a shell script, because sometimes our variable may contain wildcard * or whitespace characters, and these are interpreted by Bash in specific ways which are highly dependent on the context. If double quotes are not used when the value of the variable contains whitespace, Bash will sometimes break apart the value into separate arguments, and this could lead to inconsistent or unexpected results. If special characters like the wildcard are used and the variable is not quoted, Bash will expand the wildcard into all files from the current working directory. For example, suppose our current working directory is /home/ubuntu. If we use the following code:

var="*"
echo $var

The result printed to the console will be:

Desktop Documents Downloads Music Pictures Templates Videos

This is because the wildcard captures whatever is in the current working directory. However, if we were to use double quotes around the variable expansion, we'll get the variable's literal value:

var="*"
echo "$var"

Output:
*

Variables can also be expanded inside other variables. For example, suppose we want to set a path to a directory containing backup archives.

BACKUP_DIR="/home/ubuntu/backup"

Now suppose we want to append a backup archive's filename to BACKUP_DIR to get the absolute path to the archive:

ARCHIVE_FILE="${BACKUP_DIR}/archive_file.tar.gz"

This expands to /home/ubuntu/backup/archive_file.tar.gz.

When the value of a variable contains another variable preceded or followed by a string, it is good practice to surround the inner variable name with braces ${...} to prevent unintended globbing and word-splitting.

We'll write a simple backup script that backs up the contents of the ~/Pictures directory, using the tar command. We'll use the date command to append the date (YYYY-MM-DD) to the archive filename. We'll name this script pictures_backup.sh.

#!/usr/bin/env bash

PICTURES_DIR="/home/ubuntu/Pictures"
CURRENT_DATE=$(date '+%Y-%m-%d')

tar cvfz "Pictures-backup-${CURRENT_DATE}.tar.gz" "$PICTURES_DIR"

Make this script executable, and then execute it:

chmod +x pictures_backup.sh
./pictures_backup.sh

The resulting archive file will be in the current working directory: Pictures-backup-2026-11-02.tar.gz

If statements

An if or elif statement can be used to perform an action if some condition is true, and can be followed by an else statement if the condition is false. For example, if you want to check if the value of the EDITOR environment variable is "vim" or "nano" and print "Unknown editor" if it is neither "vim" nor "nano", you could do the following:

if [ "$EDITOR" == "vim" ]; then
    echo "Editor is vim"
elif [ "$EDITOR" == "nano" ]; then
    echo "Editor is nano"
else
    echo "Unknown editor"
fi

Depending on your use-case, the elif and else statements may not be necessary. For example, if you just want to print the Vim version information if the EDITOR environment variable is set to "vim", and then continue the execution of the rest of the script, you could do the following:

if [ "$EDITOR" == "vim" ]; then
    vim --version
fi

...remainder of script...

Storing application stdout to a variable

Application stdout (what you see on the terminal screen, with an un-piped application) can be saved and used in Bash. The simplest and most elegant way is to use command substitution, by wrapping the code in $(...).

Example

fooVar=$(who)
echo $fooVar

This code should output the current users, their respective ttys, and date of login. Note that this strips newlines. Be sure to do any parsing in-line ( | grep, etc ) and then pass it to a variable. We will try this again, but grep for tty7, the GUI's tty.

Example 2

fooVar=$(who | grep tty7)
echo $fooVar

This should output the single user that is currently logged in.

Functions

Bash lets you create a function on the fly, which is handy if you plan on using a code block more than once. Functions are typically used when you have a set of tasks you want to run more than once in the script, potentially with different inputs.

Example

Here is an example script:

echo "echo is Called"
echo "Functions are FUN!"
echo "echo is Called"

Although this example is simple, you can see that if you want to change "echo is Called" to say "foo is Called" you would have to edit twice.

Below is the same app using functions.

echoFunction() {
  echo "echo is Called"
}
fooBar() {
  echo "Functions are FUN!"
}

echoFunction;
fooBar;
echoFunction;

The script is longer now, but if you want to change the echo call, you have to edit one line, not two. It's more maintainable.

To show how functions can receive inputs, consider the following example:

greeting() {
    echo "Hello, ${1}."
}

greeting "Ubuntu"
# Output: Hello, Ubuntu.

The ${1} is a metasyntactic variable, which is a placeholder variable that represents the first argument supplied to the function. It could also be written as $1, but we use braces to avoid possible word-splitting. The braces are not strictly necessary for this case, but it's good to get in the habit of using them. Likewise, $2 or ${2} represents the second argument supplied to the function. Consider the following example:

distro_info() {
    echo "Ubuntu ${1} is a Linux distribution for ${2}."
}

distro_info "Desktop" "desktops"
# Output: "Ubuntu Desktop is a Linux distribution for desktops."

distro_info "Server" "servers"
# Output: "Ubuntu Server is a Linux distribution for servers."

Arguments supplied to functions are separated by surrounding them with quotes. In the example above, "Desktop" is substituted in place of ${1} and "desktops" in place of ${2}, because they are two separate arguments each surrounded by quotes.

Debugging

It can be useful to trace a script to find out why something does not work as expected. To trace, start it through Bash explicitly and use the -x option, like so:

bash -x ./script.sh

This will write each command to standard error (preceded by a ‘+ ’) before it is executed.

Other Scripting Languages related to Bash

tr

This is one of the most basic applications to pipe data through that uses a basic scripting syntax. In this case, it accepts regular expressions. Let's do a normally complicated task, transforming a string to all uppercase.

read foo
var=$(echo $foo | tr "{a-z}" "{A-Z}")
# {a-z} Matches a through z
# {A-Z} matches A through Z
echo $var

The output should look something like this:

this is a test
THIS IS A TEST

We can also use tr to translate strings, so let's translate all "tar" in $foo to "bar":

echo "Type in: I love tars"
read foo
var=$(echo $foo | tr "t" "b")
echo $var

The output should look something like this:

I love tars
I love bars

AWK

AWK is short for Aho, Weinberger & Kernighan.

It has its own custom scripting language, suitable for a page all by itself, so here we will only look at some basics I will cover only the basics that can help when you are bash scripting.

pidof clone

Let's make a quick pidof clone that prompts for a process identifier, then echoes the process ID:

read pname
ps -ef | grep -v grep | grep $pname | awk '{print $2}'

Let's take some pipes out and use only awk for the filtering:

read pname
ps -ef | awk -v p=${pname} '$8 ~ p { print $2 }'

Single quotes are used to pass the awk command(s). The curly braces are to use the awk language (for prints, ifs, etc.). Print prints the column passed given by the $ markup, space delimited.

The -v option allows passing a shell value into an awk variable, the $8 is a field variable (column 8 of the ps -ef command's output) and the operator ~ is a regular expression match.

There are a lot more commands than the print command, including if statements, and it is worth looking into if you are interested in using awk.

SED

Only the s/ command for substitutions with sed will be covered here.

Try this out to show that sed can not only replace in-line, but, unlike tr, can replace a string with a longer or shorter string than before:

read foo
echo $foo | sed "s/foo/bars/"

When this command is run, it should substitute the first appearance of "foo" with "bars".

This is an example of the output.

I love to go to foo
I love to go to bars
Retrieved from "https://wiki.ubuntu.com/w/index.php?title=Bash_scripting_for_beginners&oldid=1579"
Categories:
  • Tidying candidates
  • Tutorials
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.