2009-04-17 4 views

Antwort

25

Sie verwenden:

## __SCRIPTNAME - name of the script without the path 
## 
typeset -r __SCRIPTNAME="${0##*/}" 

## __SCRIPTDIR - path of the script (as entered by the user!) 
## 
__SCRIPTDIR="${0%/*}" 

## __REAL_SCRIPTDIR - path of the script (real path, maybe a link) 
## 
__REAL_SCRIPTDIR=$(cd -P -- "$(dirname -- "$(command -v -- "$0")")" && pwd -P) 
+0

Große Antwort - Ich hatte gehofft, dies würde auch funktionieren, wenn Sie das Skript, d. /some/script.sh 'aber es tut es nicht. – synthesizerpatel

+4

@synthesizerpatel: In ksh93 hast du '$ {.sh.file}', was auch für Quelldateien funktioniert. –

+1

Wie von Gruik aufgezeigt, funktioniert dies nicht, wenn es eine symbolische Verbindung zum Shell-Skript selbst gibt. Wenn Sie den Befehl beispielsweise in/usr/bin verknüpfen, gibt __REAL_SCRIPTDIR/usr/bin zurück, was (höchstwahrscheinlich) nicht das ist, was Sie wollen. Sie brauchen anscheinend readlink für diese –

7

Wie das Skript aufgerufen wurde in der Variablen $ 0 gespeichert ist. Sie können readlink verwenden die absoluten Dateinamen zu erhalten:

readlink -f "$0" 
+0

Dank Für den $ 0 Tipp, was ist Readlink? scheint nicht auf meinem System zu sein – Brabster

+0

readlink ist eine einfache Anwendung in der gnu Corutils Paket – soulmerge

+0

Hmmm brauchen etwas völlig innerhalb ksh, keine Abhängigkeiten. Danke, aber – Brabster

1

Dies funktioniert auch, obwohl es nicht dem „wahren“ Weg geben, wenn es eine Verbindung ist. Es ist einfacher, aber weniger genau.

SCRIPT_PATH="$(whence ${0})" 
1

Versuchen Sie, welches Kommando.

which scriptname 

geben Sie den vollständigen qualifizierten Namen des Skripts zusammen mit seiner absoluten Pfad

2

readlink -f wäre das Beste, wenn es tragbar war, weil es alle Links für beide Verzeichnisse und Dateien gefunden löst.

Auf Mac OS X gibt es keine readlink -f (außer vielleicht über Macports), so dass Sie nur readlink verwenden können, um das Ziel einer bestimmten symbolischen Linkdatei zu erhalten.

Die $(cd -P ... pwd -P) Technik ist schön, aber funktioniert nur Links für Verzeichnisse, um das Skript, die zu lösen, es funktioniert nicht, wenn das Skript selbst ein Symlink ist

Auch ein Fall, der nicht erwähnt wurde: Wenn Sie Starten Sie ein Skript, indem Sie es als Argument an eine Shell übergeben (/bin/sh /path/to/myscript.sh), $0 ist in diesem Fall nicht verwendbar

Ich habe einen Blick auf mysql "Binärdateien", viele von ihnen sind eigentlich Shell-Skripte; und jetzt verstehe ich, warum sie nach einer --basedir Option fragen oder aus einem bestimmten Arbeitsverzeichnis gestartet werden müssen; dies liegt daran, dass es keine gute Lösung ist die gezielte Skript

-1

Versuchen Sie es mit diesem zu suchen:

dir = $(dirname $0) 
2

Das ist, was ich tat:

if [[ $0 != "/"* ]]; then 
    DIR=`pwd`/`dirname $0` 
else 
    DIR=`dirname $0` 
fi 
4

Die Variable $ RPATH enthält den relativen Pfad zu die echte Datei oder der echte Pfad für eine echte Datei.

CURPATH=$(cd -P -- "$(dirname -- "$(command -v -- "$0")")" && pwd -P) 

CURLOC=$CURPATH/`basename $0` 

if [ `ls -dl $CURLOC |grep -c "^l" 2>/dev/null` -ne 0 ];then 

    ROFFSET=`ls -ld $CURLOC|cut -d ">" -f2 2>/dev/null` 

    RPATH=`ls -ld $CURLOC/$ROFFSET 2>/dev/null` 

else 

    RPATH=$CURLOC 

fi 

echo $RPATH 
+0

Dies scheint die einzige verfügbare Methode zu sein, die mit der Situation eines Symlinks zum Skript selbst zurechtkommt, so schrecklich es auch ist. –

6

Nun, es hat eine Weile gedauert, aber dieses hier ist so einfach, dass es schreit.

Da die CD in der erzeugten Shell mit $() arbeitet, hat sie keine Auswirkungen auf das aktuelle Skript.

8

In der Korn-Shell schlagen alle diese $ 0-Lösungen fehl, wenn Sie das fragliche Skript verwenden.Der richtige Weg, um das zu bekommen, was Sie wollen, ist $ _

Beachten Sie die letzte Zeile dort? Verwenden Sie $ _. Zumindest in Korn. YMMV in bash, csh, et al ..

+0

Diese Antwort sollte in die akzeptierte aufgenommen werden. Ich habe mich eine halbe Stunde lang bemüht, mein ksh-Skript zu finden, bis mir klar wurde, dass ich '$ _' brauche. – andreee

0

Ich verbesserte die Antwort von Edward Staudt, in der Lage zu sein, mit symbolischen Verbindungen des absoluten Weges und mit Ketten der Verbindungen auch zu beschäftigen.

DZERO=$0 
while true; do 
    echo "Trying to find real dir for script $DZERO" 
    CPATH=$(cd -P -- "$(dirname -- "$(command -v -- "$DZERO")")" && pwd -P) 
    CFILE=$CPATH/`basename $DZERO` 
    if [ `ls -dl $CFILE | grep -c "^l" 2>/dev/null` -eq 0 ];then 
    break 
    fi 
    LNKTO=`ls -ld $CFILE | cut -d ">" -f2 | tr -d " " 2>/dev/null` 
    DZERO=`cd $CPATH ; command -v $LNKTO` 
done 

Hässlich, aber funktioniert ... Nach Durchlauf dieser ist der Pfad $ cPath und die Datei ist CFILE $

0

$ Mit _ liefert den letzten Befehl.

>source my_script 

Works, wenn ich den Befehl zweimal ausgeben:

>source my_script 
>source my_script 

Wenn ich eine andere Reihenfolge der Befehle zur Verfügung:

>who 
>source my_script 

Die Variable $ _ returns "die"