About Unix and Bash

Linux is not, by itself, an operating system. Linux is a kernel, which means it's a critical part of an operating system, but the user never directly interacts with it. If you mean to use linux, you can do so in two ways.

  • You can manipulate the UI of an OS built on top of the Linux kernel. Such an OS is typically called a distribution, or 'distro'.

  • Your second choice is to interact with it more directly by using what is called a 'shell', or terminal.

  • Since User Interfaces are often different on every distro, it's more useful to learn how a typical linux shell works. Most distros use a set of standard commands in the shell. The most common language that is built out of these commands is called 'BASH', or the Bourne Again SHell, a modern implemenation of an earlier Bourne SHell.
    alt-f2 # on many linux systems, this will open a dialog where you can enter:

  • commonly, ctrl-alt-t will open a terminal as well.

  • you should get some kind of prompt that ends in a '$'. This is called a 'REPL' or 'Read Evaluate Print Loop'. This interface is used to input commands, or sequences of commands. You can write entire programs in BASH, or you can modify simple things on the fly with individual commands.

  • from now on, lines that appear as this line does will denote that the marked text is to be run as a terminal command. Type the text into the terminal and press enter..

    Directory Navigation

  • BASH is always used in the context of a filesystem and an environment. The environment stores variables which you can access. The filesystem contains your system's code, configuration, and documents. Each command in BASH is a program which is stored somewhere. Any program you install can be referenced as a command in BASH. Because of the way it interacts with the filesystem, BASH has many shortcuts for long directories:

    • a single '.' stands for the directory you are currently in.
    • a pair '..' represents the parent directory which contains the current folder.
# Every character after a '#' is a comment. 
# You don't need to add any text from beyond a '#'. 
# Try it, if you'd like.

cd . # 'change directory'
  # '.' references your current location,
  # so this command has no effect.

  # 'list semantically'
  # prints out the names of the files
  # and directories in the current directory.

In your home directory, ls should print out Documents, Downloads, and maybe some other things.

cd .. # will change into the parent directory.   
pwd #this should print '/home/'   
ls # this should print out user's home folders.   

~ represents your home folder. It is equivalent to typing /home/YOURUSERNAME/

/ represents the root of the filesystem.

try out:

cd /

This is the root of your file system.

cd ~ # this is a shortcut for your home directory.
cd # cd with no arguments brings you back home

Try either one if you don't believe me.

ls # look around after you 'cd'
cd .. # move up a directory
cd ../.. # move up two directories
cd ~/Documents # change to your documents folder
cd ~/Downloads # change to your downloads
cd /usr/ # a special protected folder at the filesystem root

These commands should be sufficient for you to navigate through most of your filesystem. You can execute a number of commands in sequence by using ';'

cd /; cd ~;pwd
your shell may support tab completion. Hit tab when you've half typed something and see if it finishes your command for you. It'll save you a lot of time ;)

Creating Custom Scripts

There are many commands, and whenever you install a program, it adds the relevant commands to your shell's default path. Anything you can execute in a command or series of commands can be made into a script, which will have its own command. Your default 'path' (the place your shell looks for custom commands) is '/usr/local/bin'.
cd /usr/local/bin
You need root permission to add files to this folder. Some folders that could possibly contain sensitive data require that you browse into them as the 'root user' in order to even read the files contained within. If something requires root privileges to modify or read, chances are you shouldn't mess with it until you understand what it does.
You can check what kind of permissions a file will require by navigating to it's location and running:
ls -l
sudo # is a command which runs the subsequent command as the root user. It stands for 'super user DO'
Many distros come with a text editor called 'gedit'. Assuming you have it installed, we will use it to write a script. open gedit with sudo
sudo gedit /usr/local/bin/myscript.sh then enter the following code exactly:

echo "hello world";   
exit 0;  

save and exit gedit, and then run
sudo chmod +x myscript.sh # this marks your script as executable
now try running it!
you should see a message. echo prints out whatever message is provided.

Using Man Pages

most commands have what is called a 'man page'. This is its manual. You exit from a man page by pressing 'q'
man ls
man cd
man pwd
you can also just ask for a reminder on its optional commands:
ls -h
ls --help
play around with the following commands
ip addr

You will also need 'rm', but DO NOT USE THIS IF YOU DON'T KNOW WHAT IT DOES. NEVER RUN COMMANDS WITHOUT UNDERSTANDING THEM. Pretty much everything other than 'rm' (so far) is harmless, but if you don't consider what you are doing, you can really mess things up.
sudo rm -Rf / --no-preserve-root #this command will wipe your filesystem completely, but it's pretty short.
If you don't believe me, try it, then get ready to reinstall your OS. This is hopefully a lesson you will remember.


I'm going to introduce a number of tricks that have vastly improved my own productivity and quality of experience with Linux. You can probably get by without most of them, but they might save you some time.

Knowledge of the command line can be compared to a martial art. You can learn all the moves, but you need to make them your own to get the most out of them. Play around whenever you learn one of them, and you'll retain it better.

I'll introduce vocabulary as necessary.

for i in *.JPG; do echo $i; done
for i in 0 1 2 3 4 5 6 7; do echo "hello" >> test$i.txt; done

  • integer arithmetic
expr 1 + 1
myvar=$(expr 1 + 1)
echo $myvar
expr $myvar + 1
expr $myvar / 3
expr $myvar \* 3
let myvar+=1
echo $myvar
let myvar+=1
echo $myvar

echo "3.4+7/8-(5.94*3.14)" | bc` 
# Floating point arithmetic using 'bc' and 'pipes'

curl ipecho.net/plain
# query a web service for your external ip address  

df -m
# disk space free in megabytes  

df -h
# disk space free in gigabytes  

du -c
# disk usage in the current directory with a total  

gedit ~/.config/user-dirs.dirs
# edit this folder on many systems 
# to change where common directories are located

Useful Tricks

  • Now that you've entered a bunch of commands, use your up arrow. It scrolls back through a list of your previous commands. This will save you a lot of typing!
  • To glance at the top of a file, without opening an editor: cat <filename> | less # escape with q
  • A similar function involves using '!!' as a symbol within a command. The shell will substitute your last command in place of '!!'. I use this when I run a command requiring root privileges, but I forget to 'sudo'. sudo !! # this will rerun the previous command with sudo
  • '*' is called called a 'wildcard', or 'Kleene Star'. It's used for pattern matching. Suppose you want to delete all the text files in a folder.
    rm *.txt # will generate a list of all the files in the current folder which are named (anythingAtAll).txt and then delete them.
  • Want to look at all your server logs from Saturday?
    cat Sat*.log | less
  • That's a pretty simple example, it can match crazier patterns..
    ls F*.* # this will list every file beginning with 'F' which includes a dot.
  • NOTE: this is case-sensitive

    takes the text output of a command and writes it to a text file.
    ls > ThingsInThisFolder.txt # makes a file which lists out all the files in this directory.

  • This will overwrite files if they exist.
    ls >> ThingsInThisFolder.txt # makes a file if it does not exist, and appends text onto it if it does.
  • '<' does the opposite, taking a file and using it as the input for a command as though you had typed it exactly as in the file.
  • The command to launch cjdroute involves using this feature. We'll get to that in a little while.
    sudo ./cjdroute < ./cjdroute.conf
  • Filenames and directories which start with a '.' are ignored by the 'ls' command. Use this notation to hide files. This also keeps it from displaying the implicit '.' and '..' which are a part of every folder.
    echo "pewpew" > .test.txt
    ls # this won't display the file .test.txt
  • A 'flag' is an optional command that indicates you want an additional feature active in a command. One such flag for 'ls' is -a.
    ls -a # this will display all the hidden files in your current directory
cat /etc/passwd # list current users

sudo shutdown -h now
sudo shutdown -h 0
sudo shutdown -h 18:45 "shutting down!"
sudo shutdown -r 0

sudo halt
sudo poweroff
sudo reboot

tar -xvsf filename.extension
tar -cvzf archive_name.tar.gz dirname/

sftp -p user@ip
ssh user@ip

blkid -o list -c /dev/null # list drives
mount /dev/sd? /mnt/??? # mount a drive
umount /dev/partitionId # unmount

sudo nmap -sS -p0-2000

Cron Jobs

A 'cron job' is an entry in your cron table file. Each entry specifies a timing pattern for periodically executing some command.

If you want to open your cron table with a specific editor (nano, for instance), do it like this: env EDITOR=nano crontab -e

Once in your editor, on an empty line, enter:

*/2 * * * * echo "pewpew" >> ~/.test.txt

Every two minutes, this cron job will be executed. the file '.test.txt' in your home directory will have the text "pewpew" appended to it.

If there are any commands you think you can automate, cron jobs are usually the best way to it.

Jobs are specified in a fairly simple format consisting of values separated by spaces, in this specific order:

  1. minute (0-59)
  2. hour (0-23)
  3. day (1-31)
  4. month (1-12)
  5. day-of-week (0-6 OR Sunday-Saturday)
  6. command-line-to-execute (any valid line of bash)
  • You can use sudo to edit the root user's cron table. This is potentially a security risk if the script in question can be edited by anyone other than the root user. Use this with caution!
  • I'll be showing some uses for this, but check out the man pages for more specifics in the meantime.
  • Below are a few more valid entries that you can try playing with.

# Execute a cron job every 5 Minutes

*/5 * * * * /home/ramesh/backup.sh

# every fifth weekday  
0 0 * * 5 echo "pewpew" >> ~/.test.txt

0 0 * * Fri echo "pewpew" >> ~/.test.txt  
0 0 1 5,10 * echo "pewpew" >> ~/.test.txt
0 0 1 May,Oct * echo "pewpew" >> ~/.test.txt

Package Management

On Debian || Ubuntu || Mint

sudo apt-get update # update your package manager's listings
sudo apt-get upgrade # install upgrades to your existing software
apt-cache search <PACKAGE> # searches your cache for any pattern ie. 'gnome*'
sudo apt-get install <PACKAGE> # install a particular package
sudo apt-get remove <PACKAGE> # remove an installed package
sudo apt-purge <PACKAGE> # uninstall and destroy configuration files
sudo rm /var/lib/apt/lists/lock # unlocks dpkg for use (use with care)
sudo dpkg --configure -a # fix damaged packages

Still curious? Get some lulz here