The Bash Environment

November 19th, 2005 Leave a comment Go to comments

The prompt after bootup is probably the most recognised feature of Unices.The shell environment allows the user complete control, but it also demands a certain degree of familiarity for effective use. There are a variety of shells available – tcsh, csh, bash, zsh, etc.

Linux systems boot to the bash shell by default. So unless you are already familiar with another shell, there is good reason to learn a bit more about the bash

The shell prompt

At your first default bootup, your bash may look like this:
[sp@localhost]: ~$

The default setting shows the username, hostname and the present working directory(here /home/sp). This default setting is not quite helpful in situations like:
[sp@localhost]: bin$

where your working directory could be any of the bin directories like /bin, /usr/local/bin, /usr/bin, or /usr/X11R6/bin. Typing pwd to find the working directory is a bit of a bother.

So, we HAVE to customise our precious shell. The files necessary are /etc/profile, /etc/bashrc(for global changes), and .bashrc and .bash_profile for customised user settings.

To begin, read the bash manpage and start about customising your shell. My bash prompt looks like this:
sp: /usr/X11R6/bin$.

For this, the prompt settings in the setup file is:
PS1="\u: \w\\$ ".

Since I have no use for my hostname displayed at the shell, it has been lopped off. Rather, the pwd is prominent.

You might be interested in reading the BASH-Prompt-HOWTO.

Directory listing

Use ls for listing the contents of your directories. These options are particularly helpful:

Scroll the list :: ls [directory] | less
List all files :: ls -a

File/Directory size :: ls -ho
File+Filetype+colour :: ls -F --color[directory]

Using the TAB Auto – complete

The automatic command line completion is probably the biggest reason why I use bash.

Want to see how it works? Here’s how:

Suppose you are in the home directory ~/ and suddenly, you need to read the documentation on something at /usr/src/linux2.2.14/Documentation/.
So, what you need to do is:

cd /u(TAB)sr(TAB)l(TAB)/D(TAB)

Easy enough? Here are a few more:
cd /u(TAB) – brings you to cd /usr/

cd /u(TAB)sr(TAB) – takes you into cd /usr/src/
If you had just entered cd /u(TAB)s(TAB), you would have seen options which match this query under the /usr directory, ie, subdirectories like /usr/sbin, /usr/share, and /usr/src.

So, now you know enough to use the TAB functionality to search a directory. Doing a ls /usr/bin/kaf(TAB) lists all the files and subdirectories starting with kaf. Suppose you downloaded a rpm, say, enlightenment-0.16.4-1.i386.rpm, and placed it somewhere and cannnot find it, worse, you do not remember the name. Do a rpm -Uvh enlig(TAB), and the package should be installed.

The cd command can be put to more extensive use too. A cd takes you directly to your home directory, cd - takes you to the last visited direcory, and a cd ~/images, will do the same thing as cd /home/sp/images.

Using aliases in bash

There is much you can do to save youself some typing drudgery by adding some aliases to your .bashrc. Of course, if you are a typing fanatic, and the commands rest in your fingers rather than your top, this is just not the sectiion for you.<g>

If you use the command line often, you will know that you use a few commands just a bit more frequently than some others. Your .bashrc in your home directory, probably contains some predefined aliases already, right out of the default setup. Open up the file in an editor and see them. You can add any number of aliases you want, just take care that they do not conflict with some other appilcation and that you remember them. A bad alias is one that you will seldom use. Here are a few that you might find useful:

alias cdup='cd ..'
– If you want to switch to the parent directory, then type cdup
alias tx='tar xzvf' – So, to untar an archive, type tx[archivename]
alias ls='ls -ho --color | more' – See your directory listings in colour
alias LDP='cd /usr/src/linux/Documentation' – To get to the docs easily

Here are the other aliases that I use :

# My aliases
# aliases for all shells

alias cp 'cp -i'
alias mv 'mv -i'
alias rm 'rm -i'
alias pwd 'echo $cwd'
alias rd 'rmdir'
alias md 'mkdir'
alias e 'vim'
alias j "jobs -l"
alias k "kill "
alias u "cd .."
alias "cd.." "cd .."

if ($?TERM == 0 || $?prompt == 0) exit

# settings for interactive shells

alias cd 'cd \!*;set prompt="`hostname`:$cwd% ";if ("$cwd" == "$home") set prompt="`hostname`% "'
alias pushd 'pushd \!*;set prompt="`hostname`:$cwd% ";if ("$cwd" == "$home") set prompt="`hostname`% "'
alias popd 'popd \!*;set prompt="`hostname`:$cwd% ";if ("$cwd" == "$home") set prompt="`hostname`% "'
set history=40
set ignoreeof
set savehist=40

# commands for interactive shells

# date
# pwd

# other aliases

alias h 'history \!* | head -39 | more'
alias more less
alias m more
alias t 'tail'
alias tf 'tail -f'
#alias . 'echo $cwd'
alias .. 'set dot=$cwd;cd ..'
alias , 'cd $dot '

alias ff 'find . -name "\!*" -print'

alias po popd
alias / popd
alias pp pushd
alias . 'pushd .'

alias open 'chmod go+r'
alias shut 'chmod go-r'
alias close 'chmod g-w,o-rwx'

#alias j 'jobs -l'
alias lo logout
alias klo logout

#alias psg 'ps -ax | grep \!* | grep -v grep'

#alias slay 'set j=`ps -ax|grep \!*|head -1`; kill -9 `echo $j[1]`'

#alias nms 'tbl \!* | nroff -ms | more' # nroff -ms
#alias tms 'tbl \!* | troff -t -ms >! troff.output &' # troff -ms
#alias tpr 'tbl \!* | troff -t -ms | lpr -t &' # troff & print
#alias ppr 'lpr -t \!* &' # print troffed

alias edit ~/bin/edit
alias help man

alias xterm 'xterm -sb -vb -bg grey85&'
alias xt 'xterm'
alias em 'emacs \!* &'
alias xem 'xemacs \!* &'
alias xx 'textedit \!* &'
alias nsc 'netscape &'
alias moz 'mozilla'
alias gho 'ghostview \!* &'
alias psl 'ps -el | grep $uid | grep -v grep'
alias psf 'ps -ef | grep kampi | grep -v grep'
alias clrback 'rm *~ *.*~ .*~ *% *.*% .*% #*# #*.*# #.*#'
alias clrtex 'rm *.dvi *.aux *.log *.ps *.toc *.bbl *.blg'
alias ex exit
alias compile 'gcc -Wall -o \!* -lm'
alias tx 'tar zxvf'
alias unpack 'gunzip \!* | tar xvf \!*'

# Variations on a theme called ls
alias ls 'ls -F'
alias l 'ls -l'
alias la 'ls -a'
alias ll 'ls -lag'
#alias ld 'ls -d *'
#alias lld 'ls -ld *'
alias lm 'ls -l | more'
alias llm 'ls -lag | more'

Here’s another list of aliases, most of them for use in Debian systems, contributed by Shanker Balan.

alias o='less'
alias dpm='dpkg' ## Rhymes with rpm ;-)
alias apti='apt-get install'
alias aptu='apt-get update'
alias dpmp='dpkg --purge'
alias dpmi='dpkg -i

Though not related to the .bashrc, you might find the keys set in /etc/inputrc to be helpful.

You can customise that too – add these bindings to the .inputrc file in your home directory to make use of the Delete, BackSpace, Home and End keys.
# This is Actually equivalent to "\C-?": delete-char
"\e[3~": delete-char
# VT
"\e[1~": beginning-of-line
"\e[4~": end-of-line
# kvt
"\e[H": beginning-of-line
"\e[F": end-of-line
# rxvt
\e[7~": beginning-of-line
\e[8~": end-of-line

Then add this line to the ~bash_profile to load the bindings:

export INPUTRC=$HOME/.inputrc

A very nice article on customising the keyboard mappings is available here.

Channeling the output

From one command to another:

This is done via a process called piping. The concept is that different commands do different things better and using them in conjuction adds value. Piping commands are usually used in the following way : [command 1| command 2| .....| command n]. As an example, suppose you want to find out the names of all the
rpms installed in your machine that have a letter X. For this, you do rpm -qa | grep x | less. This shows how searching, filtering and listing are handled by different tools but are integrated.

From commands to a file:

You can save the output of a command to a file, like ls -l > dirlist.txt, saves the contents to a file. You can also echo data to a file with echo"Whatever you want to add"

>> filename.txt.
There are some important echoing operators like >,<,>>, and 2>. Read the manpages for more info and apply them wherever needed.

Profiles

Here is an excellent .profile, contributed by Binand S Raj.

You might want to see how it goes and create one of your own. It will work on most systems, but my advice is that you check the $PATHs for your system.

#.profile follows. I have tried to comment it a bit.

### Section 1: Environment

export PS1='\u@\h[\w] '
export PATH=$PATH:/sbin:/usr/sbin:~/bin:/usr/local/bin:/usr/local/sbin:.
export NNTPSERVER=[your_nntp_server]

# Work... ;-)

export CVSROOT=[path_to_/projects/cvsroot]
export PAGER="less"

# Filenames ending with these are ignored while tab completion in
bash

export FIGNORE=.o:~:.BAK:.class

# Many programs respect this. notably gcc, mutt, slrn... No point
in
# cluttering /tmp

export TMPDIR=/tmp/[your_name]

# <control-R><something><enter>... I really need so many commands in history

export HISTSIZE=10000
export HISTFILESIZE=10000

# only for the pager less. Documented in man page.

export LESS=-S

# Removes duplicate entries from path. Protects the path from
growing too big
# during multiple invocations of bash.

export PATH=$(echo $PATH | awk -F: '
{
for (i = 1; i <= NF; i++)
arr[$i];
}
END {
for (i in arr)
printf "%s:" , i;

printf "\n";
} ')

# The next ones are excellently explained in bash's man page.

export command_oriented_history=true
export auto_resume=xsubstring
export HISTCONTROL=ignoreboth
export SIMPLE_BACKUP_SUFFIX=.BAK
export INPUTRC=~/.inputrc

### Section 2: Functions

# vi remembers the last file edited.

file=~/.profile
function vi(){
file=${@:-$file}
/usr/bin/vim $file
}

# ls and friends. These are functions because in the second case onwards,
# constructs such as lf *.c | less will also work. There is a
program called
# ld, but that one is extremely unlikely to be used from the
command line.

function l(){
ls -lFL $*
}

function lf(){

ls -lF $* | grep ^-
}

function ld(){
ls -lF $* | grep ^d
}

function ll(){
ls -lF $* | grep ^l
}

# Some OSes I have worked on don't have elm, and consequently, the frm
# program. This is a replacement. I have one version for Maildirs as well.

function frm(){
mbox=${@:-$MAIL}
( [ -f "$mbox" ] && grep "^From " $mbox
) || echo You have no mail.
}

# Empty a file. Especially a file that is getting logged to, or something.

function empty(){
for i in $*; do
if test -f $i ; then
cp -f /dev/null $i
fi
done
}

# Flush the mailq. This is a function only because I hate aliases.

function flushmail(){
/usr/lib/sendmail -q $*
}

# For this to work, I had to edit /etc/cron.daily/slocate.cron. This is a
# locate kind of command, and the sed there helps make the o/p shorter.
# Used as vi $( plocate somefile ). My home directory tends to
get really

# cluttered, and using the standard slocate and grepping is a pain.

function plocate(){
slocate --database=/home/[your_name]/.filedb $* | sed 's%/home/[your_name]/%~/%g'
}

# Swaps two files. I am surprised there is no command version.
# Useful when you want to try a config file obtained from elsewhere, and also

# keep the old version.

function swap(){
if [ $# != 2 ]; then
return 1
fi
tmpfile=/tmp/[your_name]/.swapper.$$.$RANDOM
mv -f $1 $tmpfile

mv -f $2 $1
mv -f $tmpfile $2
return 0
}

### Section 3: Aliases

# First, unalias /all/ system aliases.
unalias -a

# Only the aliases I need.
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
alias more='less'
alias mailx='mail'

### Section 4: Other Settings

if [ -n "$TMPDIR" ]; then

mkdir -p $TMPDIR
fi

# SSH stuff.

if [ $SHLVL = 1 -o -n "$DISPLAY" ]; then
eval $( ssh-agent )
ssh-add
fi

Using wildcards

You can use wildcards to substitute for complete commands. Suppose you want to remove all the html files in a directory. Just cd to the directory and type, rm *.html. You can also do selective operations with wildcards. Suppose you want to delete those html files that have a number 9 in their names, you do rm *[9]*.html. In case you want to delete files except those that have a 9 in them you”ll need to do rm *[!9]*.html.

These calls might be useful : * – all, ? – only one, [xyz] -any of the number enclosed, [x-y] – anything in the range,
[!xyz] – none of the values enclosed.

Substitution

The format for substituting commands is: command1 $(command2)

Suppose you want to kill some job, say its name is abc and its pid is xyz. All you’ve to do is kill $(pidof abc)

Using -fg and -bg

If you are working at th console and want to run an intensive program, while at the same time doing something innoucious as text editing, it is very much possible. Using the_command& runs the program in the background. You can bring the process to the foreground with fg.

Some odds and ends

This section terminates this article with a few miscellaneous tid-bits.

(ls; date) > file.txt. This line displays the dir-list and the date, and saves it to a file, especially necessary during back-ups.

./configure && make && su -c "make install". Pretty obvious.

./configure || tail config.log && rm -f config.cache. Runs configure, if not successful, lists the errors and clears the cache.

  1. No comments yet.
  1. No trackbacks yet.