Heiner's SHELLdorado
Shell Tips & Tricks (Beginner)
SHELLdorado - your UNIX shell scripting resource
HomeGood Shell Coding PracticesExample Shell ScriptsShell Scripting LinksShell Scripting Tips+TricksShell Scripting Articles

Tips&Tricks Home
  Beginner
  Intermediate
  Script Programmer
  Advanced

Submit a new Tip

  Top Next Tip
Determine where a command is
Level: Beginner Submitted by: ??? URL: none
The command "type" may be used to find out,
which command the shell executes.

Example:

    $ type ls
    /usr/bin/ls
    $ type l
    l is an alias for 'ls -l'
      

Previous Tip Top Next Tip
Suspending and resuming a command
Level: Beginner Submitted by: ??? URL: none
If you did i.e. a "telnet" to another host, but want to do
a "ls -l" on the current host, you do not have to close the
"telnet" session.

Just type "^Z" (control-z) to suspend the current telnet session.
The command is then waiting for you to resume. In this time
you get a shell prompt and can issue any command.

If you are ready to continue, you can resume the "telnet" session
with the command "fg %1" ("foreground: the first command waiting").

If you want to run the command in the background, you could
issue a "bg %1" ("background: first command waiting"), too. 

The command "jobs" lists all commands waiting.


      

Previous Tip Top Next Tip
Using arrow keys in kornshell
Level: Beginner Submitted by: perrella@yahoo.com URL: none

Use this tip to enable your arrow keys.
Caveat: You will have to use the emacs bindings

Enjoy!

#!/bin/ksh
# file: enable-arrow
# source in current environment with 
# command:
#       . enable-arrows
#

set -o emacs

# Note: these are the actual control 
# characters. In vi, type i ctrl-v
# then ctrl-P (if u want a ctrl-p)
alias _A=^P
alias _B=^N
alias _D=^B
alias _C=^F

alias __A=^P
alias __B=^N
alias __D=^B
alias __C=^F     
      

Previous Tip Top Next Tip
Removing ^M's in imported DOS and MAC files
Level: Beginner Submitted by: chuck@benatong.com URL: http://www.spamtrap.com
If you have ever imported a DOS or MAC text file, you most likely have
run into the dreaded ^M's at the end of each line.
UNIX uses a newline (\n 10 or 0x0A)
DOS uses BOTH a carriage return and a newline (\r 13 or 0x0D) and \n
and MAC, just to be different, uses just a carrage return (\r)

In the UNIX world and newline is usually displayed as two characters ^M
the ^ means that this is not a printable ASCII character and is usually
spoken as "control" 
since it is the character that would be generated if the control key is
held down while typing "M"

To get rid of these unwanted characters you need the UNIX tr  (translate)
command.
I usually add an alias to my shell startup script to create easy to remember
variations
of the tr command for each purpose.

Using bash as an example, edit .bashrc and add these lines.

alias cvtMAC="tr '\r' '\n' "
alias cvtDOS="tr -d '\r' "

You now have two new commands that you can type from the command line.
To try the commands out right away, without opening a new terminal, you
need to tell bash to re-read it's startup file by typing

source .bashrc

Now you are ready to try out the new commands.

To convert a MAC file you would type
cvtMAC < MACFILE > UNIXFILE
This will read a file named MACFILE and create a file named UNIXFILE 
that has all of the \r's converted to \n's

For DOS files, you just want to remove the darn \r's
so in cvtDOS the -d tells tr to delete them.

Of course you can create tr commands that reverse this
process.

Have Fun.

chuck
      

Previous Tip Top Next Tip
Print enviroment variables in an easy to read format
Level: Beginner Submitted by: glong@openwave.com URL: none
Replace a normal environment 
variable output as in $PATH:

/usr/bin:/usr/ccs/bin:/usr/local/bin:

with:

/usr/bin
/usr/ccs/bin
/usr/local/bin

Use this SIMPLE script:

#! /usr/bin/ksh
IFS=':'
for ii in $PATH
do
        echo $ii
done
# end of file
      

Previous Tip Top Next Tip
Include the current directory within your prompt
Level: Beginner Submitted by: ??? URL: none
To include the current directory within the prompt, include
the following line into your $HOME/.kshrc (KSH) or $HOME/.bashrc
(BASH):


    PS1='$PWD $'
    export PS1
      

Previous Tip Top Next Tip
Running a script without changing file access permissions
Level: Beginner Submitted by: junkies_comp@hotmail.com URL: none
Usually a user has to change the file
permissions for a shell script to
make it executable, e.g.

	chmod +x script

Sometimes it's more convenient
to just invoke the shell with
the script as argument:

	sh script
      

Previous Tip Top Next Tip
How to set the title of a XTERM window
Level: Beginner Submitted by: ??? URL: none
The title of a XTERM window can be set using the following
escape sequence:

    ESC ] 0 ; title ^G

Example:

    echo "^[]0;This is a title^G"

Enter the escape character (the first character of the
string) as CTRL-V ESC. On the screen you will see "^[". The
last character is entered as CTRL-V CTRL-G.

      

Previous Tip Top Next Tip
Show current directory in the XTerm window title bar
Level: Beginner Submitted by: ron.perrella@bellsouth.com URL: none
This combines two tips.  Take the code for showing the current directory
in the prompt, which looks like this:

export PS1='$PWD $ '

now, enhance it with the escape codes for putting a title on your XTerm. (You
can find it easily in the tips section of Shelldorado.  I used to do this at
work, which is great because you can have a bunch of Xterms open and still
get around ok.  If you want to get fancy, change the color of the window
based on which machine you are connected to. (for ex: red for production,
yellow for test, blue for development, etc.)
      

Previous Tip Top Next Tip
Show current directory in the XTerm window title bar (2)
Level: Beginner Submitted by: "Ian P. Springer" <ips@fpk.hp.com> URL: none
Add the following lines to your .profile or $ENV file to print the
system
name and current directory in the title bars and icon descriptions of your
terminal windows.  Supports xterm, dtterm, and hpterm:

if [ "$TERM" = xterm ] || [ "$TERM" = dtterm ]; then
   alias cd=Xcd
   Xcd ()
   {
      if [ $# -ne 0 ]; then
         'cd' "$@"
      else
         'cd'
      fi
      NAME="$(uname -n):${PWD}"
      # reset name of xterm title bar & icon to $NAME
      echo "\033]0;${NAME}\007\c"  # set title bar & icon
   }
   Xcd .
elif [ "$TERM" = hpterm ]; then
   alias cd=Hcd
   Hcd ()
   {
      if [ $# -ne 0 ]; then
         'cd' "$@"
      else
         'cd'
      fi
      NAME="$(uname -n):${PWD}"
      LEN=`echo "$NAME\c" | wc -c`
      # reset name of hpterm title bar & icon to $NAME
      echo "\033&f0k${LEN}D${NAME}\c"   # set title bar
      echo "\033&f-1k${LEN}D${NAME}\c"  # set icon
   }
   Hcd .
fi

      

Previous Tip Top Next Tip
Welcome the user as they login to the system
Level: Beginner Submitted by: ??? URL: none
tt=`date +"%T" | cut -c1-2`
NAME=`grep "^$LOGNAME" /etc/passwd | awk -F: ' {print $5}'`
echo "\n\n\n"
tput smso
if [ $tt -gt 0 -a $tt -lt 12 ]
then
	echo " $NAME !!!!!!    GOOD MORNING !!!!!!"
elif [ $tt -gt 12 -a $tt -le 16 ]
then
	echo " $NAME !!!!!!	GOOD AFTERNOON !!!!!!"
else
	echo " $NAME !!!!!!	 GOOD EVENING !!!!!!"
fi
tput rmso

      

Previous Tip Top Next Tip
Displaying only the subdirectories from the current directory
Level: Beginner Submitted by: themanfromhardwar@yahoo.com URL: none
some time U don't remember the name of the subdirectory U want to go to.
and in the jungle of files and directories it is easier if you could see
only the directories.

put the following function in your env file 

dir()
{
  ls -l |awk '{ if ( substr($1,1,1)== "d") {print}}'
}
      

Previous Tip Top Next Tip
Displaying only the subdirectories from the current directory (2)
Level: Beginner Submitted by: hari.baskar@geind.ge.com URL: none
Here is an easier command to list sub-directories alone in directories

ls -l | grep ^d
      

Previous Tip Top Next Tip
Displaying only the subdirectories from the current directory (3)
Level: Beginner Submitted by: david@carter-hitchin.clara.co.uk URL: http://www.carter-hitchin.clara.co.uk/
ls -d */
      

Previous Tip Top Next Tip
Bookmark and browse directories
Level: Beginner Submitted by: gnanaprakashj@yahoo.com URL: none
Enter the following two functions in your .profile or .kshrc (if your
.profile calls it).

function mark {
    Usage="Usage: mark word"
    case $# in
        1) export "$1=cd `pwd`" ;;
        *) echo "Incorrect Arguments count "
            echo $Usage ;;
    esac
}

function goto {
    Usage="Usage: goto word"
    case $# in
        1)  if env | grep "^$1=cd " > /dev/null ; then
                eval $"$1"
                #echo "New current directory is `pwd`"
            else
                echo $Usage
            fi ;;
        *)  echo "Incorrect Argument count"
            echo  $Usage  ;;
    esac
}

If you are in a particular directory, you just have bookmark the directory
like "mark <keyword>", eg "mark tst", you can go to any number of directories
randomly and at any point of time if you want to return back to your test
directory just say "goto tst".

I normally have to move around many directories and find this bookmarking
functions very useful.

Try it. Happy directory browsing.

Note: It is valid only for the current shell.
      

Previous Tip Top Next Tip
Finding files recursively which match a certain pattern
Level: Beginner Submitted by: hari.baskar@geind.ge.com URL: none
"grep" can search a particular file or files in current directory for
matching a pattern. 

If anybody wants to search files recursively from the current directory
which match a particular pattern
the following script can be used.

Put the following script in a file.


if [ $# -ne 2 ]
then
   echo "Usage : $0 <search pattern for files> <string to be searched>"
   echo
   exit
fi

PWD=`pwd`
for file in `find $PWD -name "$1"`
do
  grep -l "$2" $file
done

 
For Example ,if you want to find a string called "execption" in all *.java
files recursively under the directory.

scriptfilename *.java exception
      

Previous Tip Top Next Tip
Finding files recursively which match a certain pattern (2)
Level: Beginner Submitted by: ??? URL: none
The following command can be used to
execute "grep" not only in the current,
but in all subdirectories:

    # rgrep - recursive "grep"
    [ $# -lt 1 ] && exec echo "usage: grep search [file ...]"

    search=$1; shift
    [ $# -lt 1 ] && set -- .

    find "$@" -type f -print |
        xargs grep "$search"
      

Previous Tip Top Next Tip
Finding files recursively which match a certain pattern (3)
Level: Beginner Submitted by: ??? URL: none
find . -name *.java -exec grep -Hn "SEARCH_STRING" {} \;
      

Previous Tip Top Next Tip
Show PATH elements one per line
Level: Beginner Submitted by: ??? URL: none
Using the 'tr' (translate) command in a function can yield some handy
"shortcuts":

path ()
{
        echo $PATH | tr ':' '\n'
}
manpath ()
{
        echo $MANPATH | tr ':' '\n'
}

These functions will spit out the elements of a PATH, one per line.
You can add these functions in your .profile or some other "rc" file,
or use the nifty autoload feature of the ksh.
      

Previous Tip Top Next Tip
Show PATH elements one per line(2)
Level: Beginner Submitted by: janis.papanagnou@hotmail.com URL: none
#!/bin/ksh
# for ksh'93

print - ${PATH//:/\\n}
      

Previous Tip Top Next Tip
To reverse a file
Level: Beginner Submitted by: jeyachitra@yahoo.com URL: none
#If @ is used anywhere in the file to be reversed, use any other
special character that is not used 

ctr=`cat filename|wc -l `
line=`sed 's/$/@/g' filename |tr -d "\n"`
while test $ctr -ne 0
do
        echo $line|cut -d"@" -f$ctr
        ctr=`expr $ctr - 1`
done
      

Previous Tip Top Next Tip
To reverse a file(2)
Level: Beginner Submitted by: ??? URL: none
The following commands can be used to
reverse the sequence of lines in a file:

    nl -ba FILE | sort -nr | cut -f2-

"nl -ba" numbers all lines in the file (including empty lines), "sort -nr"
sorts the lines in descending order, and the "cut" command finally removes
the line numbers again.
      

Previous Tip Top Next Tip
To reverse a file (3)
Level: Beginner Submitted by: it_ritesh@yahoo.com URL: none
The following commands can be used to
reverse the sequence of lines in a file:

  $ tail -r filename > reverse_file

with ``tail" -r option causes the input to be displayed in reverse order
and it display full file.

[This works with Sun's Solaris]
      

Previous Tip Top Next Tip
improved cd
Level: Beginner Submitted by: themanfromhardwar@yahoo.com URL: none
the purpose of the improved cd is to change to a directory when you
remember only partly the name of directory you want to go.

create an alias in your .profile

    alias cd="cdh"

and then you need to create a function as follows in your env file

cdh()
{
    if [ $# = 0 ]; then
       cd
    else
	case $1 in
	.)  echo "you are already in " ;;
	..) thisdir=`pwd`
	    prevdir=`dirname $thisdir`
	    cd $prevdir ;;
	*)  counter=`ls -l | grep "^d.*$1" |awk '{print $9}' |wc -l`
	    counter=`expr $counter + 0`
	    case $counter in
	    1)	cd `ls | grep "$1"`
		pwd ;;
	    0)	if test -d $1
		then cd $1
		else echo "no such directory"
		fi ;;
	    *)	echo "the options are"
		for i in *$1*
		do test -d $i && echo "$i"
		done ;;
	    esac ;;
	esac
    fi
}
      

Previous Tip Top Next Tip
Returning to the starting directory
Level: Beginner Submitted by: narahari@tc4hq.cmcltd.com URL: none
When you are working in a directory and you suddenly want to jump to
another 
directory, and from there to another , but finally return to your starting 
point(directory) how do you do it ?

Have the the following shell functions in your  .profile or 
In a run control file like .kshrc if you work in K shell.
gt(){
prev=`pwd`
cd $1
} 
rtn(){
cd $prev
echo "Returned back to $prev"
}    

Now these functions are active as soon as you login.  Suppose you are in
/users/dummy1/salaryprog/reports/archives/2001/br-1001. You have been happily
working there . Then suddenly you wanted to go to  root. And from there
to /usr/lib.  And now you want to return back to your starting point. In
such cases
You should use the command  'gt' for the first jump, and  'cd' for the
subsequent jumps. At the point when you want to return to your starting
directory, say 'rtn' simply. 
Lo,  pat  you are back into your
users/dummy1/salaryprog/reports/archives/2001/br-1001. In contrast to the
ksh "cd -" command (which returns to the last directory) any directory can
be remembered for later return.
      

Previous Tip Top Next Tip
Repeat any command, not only the last
Level: Beginner Submitted by: jeex@libero.it URL: none
We know we can repeat the last command starting with a specified word,
for example: !vi (bash) or r vi (ksh). 
Sometimes I need to look for a file object of the command and not for the
command itself; so I wrote a little function:

cmd ()
{
   history | tail -${2:-10} | awk -v tofind=${1:-[0-9]} '($0!~/ cmd /) &&
   ($0~tofind) { print }'

}

its execution is simple:

$ cmd [<to_find>] [<tail_element>]

If you run cmd alone you pick one of the last commands except "cmd" itself
from the last 10 lines of the history file.

$ cmd

If you specify the <to_find> variable you pick all the commands matching
your criteria

$ cmd bash

If you specify <tail_element> option and <to_find> variable you pick all
the command matching your criteria in the last <tail_element> rows

$ cmd bash 30
      

Previous Tip Top Next Tip
Echo and nested commands
Level: Beginner Submitted by: johngnub@cox.net URL: none
Cool ways to use shell comands in a echo statement. 
echo "$0 Today `date`"
Or. . .
echo "$0 Today `date` `uname -n` "

Those two will print out the date, and name on the same line with the vars
and fixed text. Want more then one line? Note the ";". 
echo "$0 `date ; uname -n` "

Some thing more complex. Set a var, then use eval to run the command. 
FOO="ls |wc -l"
echo "$0 `date` File count = `eval $FOO` "
Note the use of eval to run the $FOO var.
      

Previous Tip Top Next Tip
Sum of Digits of a Number
Level: Beginner Submitted by: jaduks@hotmail.com URL: http://jaduks.livejournal.com
Here is a simple way to calculate the sum of all digits of a number:
$ expr `echo "123671" | sed -e 's/[0-9]/ + &/g' -e 's/^ +//g'`
20
      

   
Copyright © 1998-2014 Heiner Steven (heiner.steven@shelldorado.com)