# Customizing the Shell and Vim

## Overview

The shell and Vim offer a minimal interface without check boxes, buttons, or other obvious settings. However, there are actually many possible settings we can configure. This is done by writing configuration files which are hidden files beginning with a '.' in your home directory.

Some configurations are for convenience, while others may be necessary for certain tasks. We will begin discussing customizing the bash shell, and then move onto the Vim text editor.

## Environment Variables

One type of setting in Unix is the environment variable which is a variable associated with your shell session. We can list all current environment variables, along with their values, using the env command. A subset of the env output I get is shown below:

finlaysoni@myvm:~$env LANG=C.UTF-8 XDG_SESSION_ID=234 USER=finlaysoni PWD=/home/finlaysoni HOME=/home/finlaysoni LC_CTYPE=en_US.UTF-8 SSH_CLIENT=173.71.216.216 59162 22 XDG_DATA_DIRS=/usr/local/share:/usr/share:/var/lib/snapd/desktop SSH_TTY=/dev/pts/0 MAIL=/var/mail/finlaysoni TERM=xterm SHELL=/bin/bash SHLVL=1 LOGNAME=finlaysoni XDG_RUNTIME_DIR=/run/user/1001 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin LESSOPEN=| /usr/bin/lesspipe %s _=/usr/bin/env OLDPWD=/home/finlaysoni/project1  The meanings of some of these variables are described below:  Variable Meaning TERM What type of terminal you are using, different terminals support different capabilities such as the number of colors. SHELL Which shell program you are using. This course assumes the default bash shell, but there are others. USER Your user name. PATH The directories to search for commands. This is covered in more detail below. PWD Your present working directory. OLDPWD The present working directory you were most recently in. This is used to support the cd - command which takes you to the OLDPWD. LANG Which language to display output in. HOME Your home directory. _ The last command you ran. We can also output the value of a specific environment variable with the echo command: finlaysoni@myvm:~$ echo $USER finlaysoni  echo can be used to output any text. Anything following a$ sign is treated as an environment variable and has its value output instead:

finlaysoni@myvm:~$echo Hello$USER, you are using the $SHELL shell. Hello finlaysoni, you are using the /bin/bash shell.  Most of these variables are set by the shell itself, and you will not want to change them. However, there are other environment variables which have a special meaning which we can set. One important one is the$EDITOR variable which several programs use to determine which text editor to bring up when you need to edit text.

You can set this variable with the export command as follows:

export EDITOR="vim"


The syntax of a setting an environment variable is important. There can not be any spaces around the "=" sign! In most programming languages, it's common to put spaces around the "=", so be sure you don't make that mistake.

Another environment variable you may want to set is the PS1 variable which stands for "prompt string 1" and is the text that appears to the right of where you enter commands. It can consist of any text along with special codes for specific information. For example the default PS1 variable is:

finlaysoni@myvm:~$echo$PS1
$\e]0;\u@\h: \w\a$${debian_chroot:+($debian_chroot)}\u@\h:\w\$ bash substitutes your user name for '\u', the host name for '\h' and so on. We can change the prompt by overwriting the PS1 variable: finlaysoni@myvm:~$ export PS1="Enter your command: "
directory1    file1    file2


As you can see, now the shell prompts us with a custom message instead of the default. Most people like to have information in the prompt like their username, present working directory and so on.

You can create a custom PS1 with what you want in it at http://bashrcgenerator.com/ (it is tedious to do it by hand).

## The .bash_profile File

While you can enter the export command directly to the shell, that will only set the environment variable for the current session. If you log out, and then log back in, your setting will be lost. If you want to set an environment variable permanently, you will need to put it in a file called ".bash_profile".

Note: There is another similar file called the .bashrc file, which does a similar thing, but I recommend using .bash_profile instead. One reason is that if your .bashrc file produces output, it will break file transfers with FileZilla and similar programs.

Because this file name begins with a '.', it is a hidden file and is not displayed by ls by default. You can edit this file in Vim:

finlaysoni@myvm:~$vim ~/.bash_profile  The file will likely be empty if you have never opened it before, or it may contain some default settings in it. The .bash_profile file is a list of commands that the bash shell will execute, from top to bottom, each time you login. We can place any commands we like in the file and they will be run at each login. For example, if we place the export EDITOR="vim" command on a line at the end of .bash_profile, then each time we login, the EDITOR variable will be set first thing. If we put the line "echo Welcome Back!" in the .bash_profile, then we will get that message displayed to us each time we login. The .bash_profile file is really a shell script and can contain programming elements which we will discuss later in this course. They can also contain comments which begin with the pound sign (#). If we want to run the .bash_profile file without logging out and back in, we can do so with the source command which takes a file name as an argument and executes all of the commands in it: finlaysoni@myvm:~$ cat .bash_profile
# set the editor and prompt string
export EDITOR="vim"
export PS1="[\u@\h \W]\$" # give a greeting echo "Welcome back!" finlaysoni@myvm:~$ source .bash_profile
Welcome back!
[finlaysoni@myvm ~]$ Notice that the cat command prints the contents of a file to the screen. I did this so you can see what's in the file. When we run it with the source command, it sets EDITOR and PS1 (changing the prompt), and also prints a greeting. By running source we run all of the commands in the .bash_profile file. Just editing the file does not do anything until the next time you log in. ## The PATH Variable One of the most important environment variables is the PATH variable, which refers to a list of locations that the shell will search in order to find the commands that you type. My PATH is: finlaysoni@myvm:~$ echo $PATH /home/finlaysoni/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:.  The PATH contains a list of directories separated by ':' characters. Mine contains the following directories: • /home/finlaysoni/bin - A directory in my home directory where I put my own personal scripts and programs. • /usr/local/sbin - Programs installed locally which are runnable by the root user. • /usr/local/bin - Programs installed locally which are runnable by any user. • /usr/sbin - Programs runnable by the root user. • /usr/bin - Programs runnable by any user. • /sbin - Important programs runnable by the root user. • /bin - Important programs runnable by any user. • /usr/games - Games. Yes there are command-line games. Try installing the package "nethack-console" and running the "nethack" command. • /usr/local/games - Games installed locally. • /snap/bin - Programs installed with the "snap" tool. • . - The current directory. When you type a command at the prompt, the directories in your PATH are searched in order for a file with the same name as the command. As soon as a match is found, that file is executed. We can see where in the PATH a given command is by running the which command. which takes an argument and searches the PATH for it, when found it tells you which directory it finds it in: finlaysoni@myvm:~$ which ls
/bin/ls
finlaysoni@myvm:~$which cal /usr/bin/cal finlaysoni@myvm:~$ which reboot
/sbin/reboot
finlaysoni@myvm:~$which nethack /usr/games/nethack  By default PATH does not contain /home/finlaysoni/bin or ".", but I find that both are helpful, so I add them with this line in my .bash_profile: export PATH="/home/finlaysoni/bin:$PATH:."


Note that this line adds to the default PATH because $PATH appears on the right hand side of the equal sign. This expands to the default PATH, and /home/finlaysoni/bin is placed first (so it is searched first), and "." is placed last (so it is searched last). When installing some programs manually, they will instruct you to add the installation directory to your PATH. This is so you can execute the installed programs just by entering their names, without specifying the whole directory name. Programs installed with apt install don't require this. ## Creating Aliases Aliases allow you to create your own commands which expand to other commands by the shell. For example, one alias I have is the ll command which is short for ls -l, but easier to type. To create this alias, the following line is in my .bash_profile: alias ll="ls -l"  The alias command creates an alias whose name is on the left side of the equal sign, which expands in to whichever command is on the right side. After running the alias command, any time we run ll, the shell will instead run ls -l. As with environment variables, there can be no spaces around the "=" sign! Aliases can also be used to automatically always pass certain options to commands. For example, if we wanted to use the safer "interactive" option for rm which asks us to confirm the deletion of files, we could use this alias: alias rm="rm -i"  Now, whenever we run rm, the shell will instead run rm -i, and pass the remaining arguments after that: finlaysoni@myvm:~$ alias rm="rm -i"
finlaysoni@myvm:~$rm a.txt rm: remove regular empty file a.txt'? n  If we wish to use a "raw" unaliased version of a program which we have aliased in this way, we can specify the full path: finlaysoni@myvm:~$ /bin/rm a


If we want to remove an alias, we can do so with the unalias command:

finlaysoni@myvm:~$unalias rm  Of course if the alias is in our .bash_profile file, it will be re-created the next time we log in, or source the file manually. Aliases are handy for making shortcuts out of the commands you most frequently use, and for automatically specifying the options that you use most. ## The .vimrc File Vim also has an initialization file which is called .vimrc and located in your home directory. Because it begins with a '.', it is also hidden. You can edit the file with: finlaysoni@myvm:~$ vim ~/.vimrc


Like the .bash_profile file, .vimrc contains Vim commands which Vim will automatically execute when it is launched. The .vimrc file can also contain comments which begin with the " character.

Vim has a number of options which can be set with the set command. For example, to turn on line numbers, we could place the following line in our .vimrc:

" turn line numbering on
set number


To turn off an option, we preface it with the word "no". For example, to turn off line numbering, we'd use:

" turn line numbering off
set nonumber


Note that we can also set those options dynamically inside of Vim itself by entering them as commands after the colon character:

:set number


In the .vimrc file, no colon is needed.

The list below gives some Vim options which may be helpful for interactive use, or for setting in your .vimrc file:

• set number

Turn on line numbering in the left margin. This is helpful when programming since you can see what lines an error is on, for instance.

• set cursorline

Highlight the line the cursor is on. This can make it easier to see where you are in the file.

• set tabstop=4

Sets the size that a "TAB" character is displayed as. Any number you like can be substituted for 4.

• set shiftwidth=4

Sets the size of an automatic indentation. Any number you like can be substituted for 4.

• set expandtab

Inserts shiftwidth many space characters when you hit the tab key. Tabs vs. spaces is a hotly contested topic among programmers, but if you like spaces, turn this on. I strongly prefer spaces by the way.

• set autoindent

Automatically indent lines when hitting the enter key. For instance, if a line is indented one level, and we hit enter, the next line will be indented one level as well. Good for Python programming.

• set cindent

Automatically indent based on the rules of C-based programming languages. For example, if we end a line with a { character, and hit enter, the next line will be indented one additional level. Good for programming in C, C++, Java, PHP etc.

• set incsearch

Search incrementally, showing results as you type the search string.

• set hlsearch

Highlight all search results.

## Vim Color Schemes

You can also change the Vim color scheme in your .vimrc file using the colorscheme option. For example, to switch to the "desert" colorscheme, you could place the following in your .vimrc:

colorscheme desert
`

A list of the color schemes which come with Vim is given below.

• blue
• darkblue
• default
• delek
• desert
• elflord
• evening
• industry
• koehler
• morning
• murphy
• pablo
• peachpuff
• ron
• shine
• slate
• torte
• zellner

The actual colors you see are also dependent on your terminal. For example, one of the color schemes above might make keywords in a program appear "blue", but the actual shade of blue is dependent on settings in your terminal.