next | next | up | down | Inhalt | Uebungen | Complete | Kommentar

all, section 7.4.

7.4.  type which

type zeigt zwar was die aktuelle Shell über einen Kommandonamen denkt, aber ein Shell-Skript wird normalerweise PATH selbst setzen. Kernighan und Pike führen ein Kommando which vor, das die Pfad-Suche simuliert:

 1      #!/bin/sh
 2      
 3      : ${1:?'no command name'}
 4      
 5      for path in `echo $PATH | sed 's/^:/.:/
 6                                      s/:$/:./
 7                                      s/::/:.:/g
 8                                      s/:/ /g'`
 9      do      if [ -x $path/$1 ]
10              then    echo $path/$1
11                      exit 0
12              fi
13      done
14      exit 1

Das Skript sollte mehrere Argumente erlauben und alle Fundstellen ausgeben:

 1      #!/bin/sh
 2      
 3      paths=`echo $PATH |
 4      sed -e 's/^:/.:/'       \
 5          -e 's/:$/:./'       \
 6          -e 's/::/:.:/g'     \
 7          -e 's/:/ /g'`
 8      exit=1
 9      
10      for name
11      do      for path in $paths
12              do      [ -x $path/$name ] && exit=0 echo $path/$name
13              done
14      done
15      exit $exit

Ein Skript sollte grundsätzlich PATH setzen, um absichtliche oder unabsichtliche trojanische Pferde zu vermeiden. Außerdem sollte ein Argument mit / nicht gesucht werden. Ein Katalog ist kein nützliches Resultat. Letztlich besteht die Möglichkeit, daß test -x (noch) nicht verfügbar ist:

 1      #!/bin/sh
 2      
 3      paths=`echo $PATH |
 4      PATH=/usr/ucb:/bin:/usr/bin \
 5      sed -e 's/^:/.:/' -e 's/:$/:./' \
 6          -e 's/::/:.:/g' -e 's/:/ /g'`
 7      PATH=/usr/ucb:/bin:/usr/bin
 8      exit=1
 9      
10      if [ -x /tmp ] 2> /dev/null     # not every test has -x
11      then    has_x=yes
12      else    has_x=
13      fi
14      
15      executable() { # path
16              if [ "$has_x" ]
17              then    [ ! -d "$1" -a -x "$1" ]
18              else    [ `expr "\`ls -l \"$1\" 2> /dev/null \
19                         \`" : '-..x'` = 4 ]
20              fi
21      }
22      
23      for name
24      do      case $name
25              in */*)
26                executable "$name" && exit=0 echo "$name"
27              ;; *)
28                for path in $paths
29                do
30                  executable "$path/$name" &&
31                  exit=0 echo "$path/$name"
32                done
33              esac
34      done
35      exit $exit

Um am Schluß keinen Zeilentrenner auszugeben, benötigen manche Versionen von echo die Option -n, andere schließen den Text mit \c ab.


back | next | up | down | Inhalt | Uebungen | Complete | Kommentar


Created by unroff & hp-tools. © by Hans-Peter Bischof. All Rights Reserved (1997).

Last modified 03/July/97