Your Federal Quarterly Tax Payments are due April 15th Get Help Now >>

Tower of Hanoi by yantingting

VIEWS: 11 PAGES: 35

									                  Shell Games
• Objective: To introduce students to the concept of
  a shell, effective use of the shell, the shell as
  programming language, and shell scripts. We will
  use the bash shell for the examples and details
  provided.
   –   Shell syntax and commands
   –   history and command completion
   –   job control
   –   variables
   –   programming constructs
   –   scripts
                       shell
•   command interpreter (bash, sh, csh,…)
•   .bashrc, .profile
•   PATH and shell variables
•   metacharacters
•   history and command completion
•   file redirection
•   pipes
•   process management
        What does the shell do?
• In Unix, separate from the OS (change look and
  feel)
• reads and executes commands
   – some handled by the shell itself (pwd, echo,…)
   – some are programs stored in some directory (look in
     directories in PATH). Start a subshell to execute these
• Provides support for better interaction with the
  computer/OS (command history, editing,
  configuration)
• Programming language
          Executing a Command
• After reading a command, the shell may do some
  processing (see wildcards etc in the syntax description that
  follows), then it must find a program to execute the
  command.
• Some commands are executed directly by the shell. Other
  commands are executed by separate programs. These are
  found by looking in a list of directories for programs with
  the appropriate name. The shell searches directories in the
  PATH variable. A hash table is used to make the search
  fast. You can add new commands simply by adding new
  programs (a program can be any executable file including
  scripts – review Unix permissions) to directories in the
  PATH. You can modify/add directories in the PATH.
    Finding out about Commands
•   type echo
•   which echo
•   info echo
•   man echo

• info bash
                                        Example
[jjohnson@ws44 cs265]$ which echo
/bin/echo
[jjohnson@ws44 cs265]$ type -a echo
echo is a shell builtin
echo is /bin/echo
[jjohnson@ws44 cs265]$ help echo
echo: echo [-neE] [arg ...]
   Output the ARGs. If -n is specified, the trailing newline is
   suppressed. If the -e option is given, interpretation of the
   following backslash-escaped characters is turned on:
      \a alert (bell)
      \b backspace
      \c suppress trailing newline
      \E escape character
      \f form feed
      \n new line
      \r carriage return
      \t horizontal tab
      \v vertical tab
      \\ backslash
      \num the character whose ASCII code is NUM (octal).

  You can explicitly turn off the interpretation of the above characters
  with the -E option.
            Notes about PATH
• If you do not have . in your PATH, commands in
  your current directory will not be found. You may
  or may not want to add . to your PATH. If you do
  not and want to execute a command in the current
  directory
   – ./command
• The PATH is searched sequentially, the first
  matching program is executed. Beware of naming
  your executables test as there is another program
  called test and this may be executed when you
  enter
   – test
                                       PATH
[jjohnson@ws44 software]$ echo $PATH
/usr/local/FrameMaker/bin:/home/jjohnson/bin:/usr/local/gpl/mpich-
     1.2.4/bin:/usr/local/bin:/usr/sbin:/sbin:/usr/openwin/bin:/opt/SUNWspro/bin:/usr/ccs/bin
     :/usr/ucb:/usr/sbin:/usr/bin:/etc:/usr/etc:/usr/UTILS/publisher/bin:/usr/bin/X11:/bin:/usr/
     remote/alg_soft/linda2.5.2sol2.3/bin:.
[jjohnson@ws44 software]$ PATH=${PATH}:/home/jjohnson/software
[jjohnson@ws44 software]$ echo $PATH
/usr/local/FrameMaker/bin:/home/jjohnson/bin:/usr/local/gpl/mpich-
     1.2.4/bin:/usr/local/bin:/usr/sbin:/sbin:/usr/openwin/bin:/opt/SUNWspro/bin:/usr/ccs/bin
     :/usr/ucb:/usr/sbin:/usr/bin:/etc:/usr/etc:/usr/UTILS/publisher/bin:/usr/bin/X11:/bin:/usr/
     remote/alg_soft/linda2.5.2sol2.3/bin:.:/home/jjohnson/software
                     Aliases
• Commands can be aliased (renamed) to alter their
  behavior. A common used of aliases is to add
  options to the default behavior of certain
  commands (e.g. ls, rm, mv, …)
• It is common practice to alias rm to prompt the
  user to make sure that the specified files should be
  removed. This is especially important since you
  can remove all files with (see wildcards)
   – rm *
• To see current aliases, use the alias command, this
  can also be used to set new aliases.
                                      Aliases
[jjohnson@ws44 jjohnson]$ alias
alias cd..='cd ..'
alias cp='cp -i'
alias d='ls'
alias df='df -h -x supermount'
alias du='du -h'
alias kde='xinit /usr/bin/startkde'
alias l='ls'
alias la='ls -a'
alias ll='ls -l'
alias ls='ls -F --color=auto'
alias lsd='ls -d */'
alias md='mkdir'
alias mv='mv -i'
alias p='cd -'
alias rd='rmdir'
alias rm='rm -i'
alias s='cd ..'
[jjohnson@ws44 jjohnson]$ type rm
rm is aliased to `rm -i'
                       Shell Syntax
• Comments
      – # This is a comment
      – ls # list the files in the current directory
• Line continuation
      – echo A long \
      – > line
• ; #Command separator – you can list more than
  one command per line separated by ;
      – ls ; who
• \      #Pathname separator
      – cd \home\jjohnson
                   Shell Syntax
• Wildcards, and pathname expansion
  –   *       # match any string
  –   ?       # match any single character
  –   [set] # match characters listed in set (can be range)
  –    [!set] # mach any character not given in set
• Examples
  –   ls *.c
  –   ls *.?
  –   ls *.[Hh][Tt][Ll]
  –   ls [a-z]
                   Shell Syntax
• File redirection and pipes
   –   < # redirect input from specified source
   –   > # redirect output to specified source
   –   >> # redirect output and append to specified source
   –   | # pipe the output from one command to the input to
       the next
• Examples
   –   grep word < /usr/dict/words
   –   ls > listing
   –   ls >> listing
   –   ls -l| wc -l
                  Shell Syntax
• Note file redirection of standard output [stdout]
  does not include error messages, which go to
  standard error [stderr] (when you are in a terminal
  session, both stdout and stderr go to the screen;
  however, when you redirect stdout to a file, stderr
  still goes to the screen).
• stdout is designated by the file descriptor 1 and
  stderr by 2 (standard input is 0)
   – To redirect standard error use 2>
   – ls filenothere > listing 2> error
   – ls filenothere 2>&1 > listing # both stdout and stderr
     redirected to listing
                  Shell Syntax
• Background jobs
  – & # run command in the background
  – grep „we.*‟< /usr/word/dict > wewords &
  – This runs the grep command in the background – you
    immediately get a new prompt and can continue your
    work while the command is run. Note that the output
    was redirected otherwise you would lose it.
  – To find out the jobs that are running in the back use the
    command jobs (also see the command ps)
  – To stop a job use the kill command (you need to know
    the process id of the job [use –l option to jobs or ps]
                                     Example
jjohnson@HILBERT ~
$ find / -name me -print &
[1] 1936

jjohnson@HILBERT ~
$ jobs -l
[1]+ 1936 Running            find / -name me -print &

jjohnson@HILBERT ~
$ ps
    PID PPID PGID WINPID TTY UID STIME COMMAND
   1608   1 1608   1608 con 1000 21:52:42 /usr/bin/bash
   1936 1608 1936   1816 con 1000 09:18:03 /usr/bin/find
   2036 1608 2036   1488 con 1000 09:18:07 /usr/bin/ps

jjohnson@HILBERT ~
$ kill 1936

jjohnson@HILBERT ~
$ jobs
[1]+ Terminated    find / -name me -print
                  Shell Syntax
• Control characters (hold the Ctrl key and the
  specified key at the same time)
   – CTRL-C # interupt – default behavior is to stop the
     current command – this is very handy for infinite loops,
     pages of output, etc.
   – CTRL-\ # quite – use when CTRL-C does not stop the
     current command
   – CTRL-Z # suspend the current command, you can
     continue the command either in the foreground with fg
     or the background with bg
   – CTRL-D # end of input (useful when entering input
     from standard input, stdin)
                        quoting
• Sometimes you do not want the shell to interpret
  metacharacters such as * or > when entering a
  command. Use single quotes to prevent the shell
  from evaluating an expression.
   – echo 2 * 3 > 5 is a valid inequality
   – echo „2 * 3 > 5 is a valid inequality‟
   – echo „2*3 > 5‟ is a valid inequality
• There are two types of single quotes (forward and
  back – the previous quote was a forward quote).
  back quote has a different meaning – it causes the
  shell to evaluate the expression in the back quotes.
   – echo `2 * 3 > 5` is a valid inequality
                    quoting
• Alternatively, you can turn of the
  interpretation of special characters one at a
  time with backslash-escaping
  – echo 2 \* 3 \> 5 is a valid inequality
                  variables
• Arbitrary variables can be used in the shell,
  assign with =, and obtain value with $.
  – name=jeremy
  – echo $name
• Sometimes it is useful to include the value
  of a variable as part of another expression.
  – echo ${name}.file
       Environment Variables
• Variables defined are not passed, by default,
  to subshells (recall that every time a
  command is executed another shell is
  created to run the command). To export
  variables so that they are passed to subshells
  use the export command.
  – NAME=jeremy
  – export $NAME
        Environment Variables
• Environment variables are typically used to
  configure your environment and to store useful
  information about your environment. Some of
  these are defined in the system profile file. You
  can define additional ones in your .profile file.
• Some useful Environment variables
   – USER, SHELL, HOST, PATH, PS1, PWD
• Use the command printenv to see the currently
  defined environment variables
        strong vs. weak quoting
• Single quote turns off all interpretation, sometimes
  you want partial evaluation. Weak quoting, using
  double quotes, does partial evaluation. In
  particular, variables are still evaluated

• Example
   – echo „User = $USER‟
   – echo “User = $USER”
        Simple Script Version 1
$ who | wc –l

Put this in a file called nu (make sure permission is
  set to execute)
$ cat nu
#!/bin/bash
# Return the number of users logged on
who | wc -l
              Special Variables
•   $#      the number of arguments
•   $*      all arguments
•   $@      all arguments
•   $?      return value of last command executed
•   $$      process id of shell
•   $HOME, $IFS, $PATH, $PS1, $PS2
•   $(pwd)
•   $((expr))
                Exit Status
• Every UNIX command, whether it comes
  from source code in C or some other
  language, a script, or builtin returns an
  integer code to its calling process.

• Use exit to return value

• To obtain the returned value use $?
                                        Example
$ ls
file1 file10 file2 file3 file4 file5 file6 file7 file8 file9

jjohnson@HILBERT ~/cs265
$ cat file1
stuff

jjohnson@HILBERT ~/cs265
$ echo $?
0

jjohnson@HILBERT ~/cs265
$ cat file0
cat: file0: No such file or directory

jjohnson@HILBERT ~/cs265
$ echo $?
1
               Conditional
# [ ] evaluates exit status – note must have
   surrounding spaces
if [ -z “$1” ]; then
  echo „no arguments‟
else
  echo $1
fi
               Case Statement
case $opt in
         a ) echo "option a";;
         b ) echo "option b";;
         c ) echo "option c";;
         \? ) echo 'usage: alice [-a] [-b] [-c] args...'
             exit 1;;
    esac
                    Loops
for file in *
do
  echo $file
done

for file in *; do echo $file; done
                      Loops
i=0
while [ $i –lt 10 ]
do
echo $i
i=$((i+1))
done
  Script Version 2 (Parameters)
#!/bin/bash
# Check to see if specified user is logged on
who | grep $1
  Script Version 3 (conditional)
#!/bin/bash
# Check to see if specified user is logged on
if [ -z “$1” ]; then
   echo “usage: nu username”
   exit 1
fi
who | grep $1
        Script Version 3 (for loop)
#!/bin/bash
# Check to see if specified user is logged on
if [ -z “$1” ]; then
   echo “usage: nu (username)+”
   exit 1
fi
for user $*; do
   who | grep $user
done
     Script Version 4 (while loop)
#!/bin/bash
# Check to see if specified user is logged on
if [ -z “$1” ]; then
   echo “usage: nu (username)+”
   exit 1
fi
while [ ! –z $1 ]; do
    who | grep $1
    shift
done

								
To top