|
|
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.
|
|
Last modified 03/July/97