Linux Basics

Learn the basics of operating a Linux-based operating system (OS) and take your first steps in exploitation in a Linux environment!

Easy

Linux Basics
Execution

Linux_Basics::Execution

So far, we've been referring to everything we type into the shell as a command. But in fact, most commands actually execute a program/executable. Programs are just files that represent certain operations that should be done by the computer when the file is executed/run.

Shell scripts

An easy example of an executable file is a shell script. A shell script allows you to store a set of shell commands (remember bash commands?) that can be done whenever the file is executed. To start a shell script, we open a new file and write the following lines at the beginning.

We will be writing to the script.sh file.

You may notice that we named the file with a .sh extension. But we are doing this purely for convention/neatness sake, file extensions are not required for executables in Linux.
#!/bin/bash

This line may look weird at first, but its purpose is simple. As mentioned, the Linux-based OS does not execute files based on their file extension (a concept that Windows users may be more familiar with), but rather, it reads the first few bytes of the file to identify what type of file it is! These bytes are usually referred to as magic bytes or file signatures.

For our file, the magic bytes we have are the #! (called "shebang"). And as you may read from the wikipedia reference, this magic bytes tells the OS that the file's data is supposed to be passed into the program that follows the #!, in this case that will be /bin/bash! While we've been referring to bash as just bash, the full path that the bash executable is located on the system is usually* /bin/bash.

If that was a lot to absorb, just know that this line tells our system, "Hey I would like to run the following commands through the /bin/bash program!"

Now we can just write the shell commands that we want the script to perform. The full script will look like so:


#!/bin/bash

echo "Let's learn about execution" echo "We are currently in this directory:" pwd echo "Here are some files in the current directory" ls echo "See you!"

To run the file, we need to change its permissions to make it executable. (We will cover the permissions in a later lesson, for now just copy the command)


chmod +x script.sh

Then we can execute the script by writing the path of the script as a command.


$ ./script.sh
Let's learn about execution
We are currently in this directory:
/tmp/exec
Here are some files in the current directory
script.sh
See you!

Notice that in the previous example, we were present in the /tmp/exec directory which contains the file ./script.sh. Now let's try to use the script from another directory, since it wouldn't be very useful if it could only be used while the user is in a specific directory.


$ cd /

$ # [1] $ ./script.sh bash: ./script.sh: No such file or directory

$ # [2] $ script.sh script.sh: command not found

We're faced with some errors!

Now the first attempt [1] fails because the script.sh is no longer in the same directory, therefore ./script.sh will refer to a file in the current directory which does not exist.

How do we solve this? We have to provide the correct path for the script instead!


$ /tmp/exec/script.sh
Let's learn about execution
We are currently in this directory:
/
Here are some files in the current directory
bin   cdrom  etc   lib	  lib64   lost+found  mnt  proc  run   snap  swapfile  tmp  var
boot  dev    home  lib32  libx32  media       opt  root  sbin  srv   sys       usr
See you!

What about the second attempt [2], why did that fail? If we could execute the script through the syntax in [2] that would be the most convenient for us as we don't have to remember the exact path of the script every time we wish to call it.

In fact, when we run commands usually like ls or id, we don't make use of their full/relative paths, even though the executables actually exist somewhere in the file system.


$ ls script.sh

$ /bin/ls script.sh

$ /does/not/exist/ls bash: /does/not/exist/ls: No such file or directory

What's the difference between the ls executable and our script.sh one? This is a useful concept called the PATH!

PATH

If you recall the previous lesson about environment variables, these allow us to store key-value pairs that can be passed to child processes. A particularly important variable our command shell makes use of is the $PATH environment variable.

Let's take a look at what this variable looks like on our system!


$ echo $PATH
/home/omu/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

This may look confusing, but do you notice anything of interest? Let's split up the string to make it more readable.


$ echo $PATH | sed 's/:/\n/g'
/home/ctf/.local/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin

If you were observant, you can see that /bin is listed here This is exactly why we are able to run ls without specifying its relative/absolute path! But since the directory that our script.sh is contained in (/tmp/exec) does not exist here, we aren't able to run script.sh without specifying its proper path.

Searching online, we can find a nice definition of the PATH variable's functionality!

The PATH variable is an environment variable that contains an ordered list of paths that Linux will search for executables when running a command. Using these paths means that we do not have to specify an absolute path when running a command.

baeldung.com

Now we can try to add to the PATH to allow our script.sh to be used conveniently!

First, we analyse the format of the PATH variable.


PATH=<dir1>:<dir2>:...:<dirn>

As we can see, PATH just contains a colon-separated (:) list of directories for the command shell to search through to find whether the command we are calling exists.

Therefore, to add more directories to the PATH, we can jus add our directory to the front or the back of the variable, remembering to include the separating colon (:).


$ # Add /tmp/exec to PATH $ PATH=/tmp/exec:$PATH

$ # Try it out $ script.sh Let's learn about execution We are currently in this directory: / Here are some files in the current directory bin cdrom etc lib lib64 lost+found mnt proc run snap swapfile tmp var boot dev home lib32 libx32 media opt root sbin srv sys usr See you!

With this knowledge, we can continue adding more of our custom executables and tooling to the PATH for ease of use.

Quiz

What is the absolute path of the ls executable?

What is the separator used to separate directory paths in the PATH variable?