2009-04-17 10 views

risposta

25

Si potrebbe utilizzare:

## __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

Ottima risposta: speravo che funzionasse anche se si crea lo script ". /some/script.sh 'ma non è così. – synthesizerpatel

+4

@synthesizerpatel: in ksh93, hai '$ {. Sh.file}' che funziona anche per i file di origine. –

+1

Come sottolineato da Gruik, questo non funziona se esiste un collegamento simbolico allo script della shell stesso. Quindi, se colleghi il comando in, dire,/usr/bin, allora __REAL_SCRIPTDIR restituirà/usr/bin, che è (molto probabilmente) non quello che vuoi. A quanto pare hai bisogno di un readlink per questo –

7

Come lo script è stato chiamato viene memorizzato nella variabile $ su 0. È possibile utilizzare readlink per ottenere il nome del file assoluto:

readlink -f "$0" 
+0

grazie per il suggerimento da $ 0, che cos'è readlink? non sembra essere sul mio sistema – Brabster

+0

readlink è una semplice app nel pacchetto gnu coreutils – soulmerge

+0

Hmmm ha bisogno di qualcosa di totalmente dentro ksh, senza dipendenze. Grazie però – Brabster

1

Questo funziona anche, anche se non darà il "vero" percorso se si tratta di un link. È più semplice, ma meno esatto.

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

Prova quale comando.

which scriptname 

vi darà il nome completo qualificato dello script insieme con il suo percorso assoluto

2

readlink -f sarebbe la migliore se era portatile, perché risolve ogni collegamento trovato per entrambe le directory e file.

Su mac os x non c'è readlink -f (eccetto forse tramite macports), quindi è possibile utilizzare solo readlink per ottenere la destinazione di un file di collegamento simbolico specifico.

La tecnica $(cd -P ... pwd -P) è bello, ma funziona solo per risolvere i collegamenti per le directory che portano allo script, non funziona se lo script è di per sé un link simbolico

Inoltre, un caso che non è stato menzionato: quando si lanciare uno script passandolo come argomento a una shell (/bin/sh /path/to/myscript.sh), $0 non è utilizzabile in questo caso

Ho dato un'occhiata a mysql "binari", molti di loro sono in realtà script di shell; e ora capisco perché chiedono un'opzione --basedir o devono essere lanciati da una specifica directory di lavoro; questo è perché non v'è alcuna buona soluzione per individuare lo script mirato

-1

Provare a utilizzare questo:

dir = $(dirname $0) 
2

Questo è quello che ho fatto:

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

Il $ RPATH variabile contiene il percorso relativo alla il vero file o il vero percorso per un vero file.

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

Questo sembra essere l'unico metodo disponibile che fa fronte alla situazione di un link simbolico allo script stesso, per quanto orribile lo sia. –

6

Beh, mi ci è voluto un po 'ma questo è così semplice che urla.

_SCRIPTDIR=$(cd $(dirname $0);echo $PWD) 

poiché il CD funziona nella shell generata con $() non influisce sullo script corrente.

8

Nella shell di Korn, tutte queste soluzioni di $ 0 falliscono se si esegue il sourcing nello script in questione.Il modo corretto per ottenere quello che vuoi è quello di utilizzare $ _

$ cat bar 

echo dollar under is $_ 
echo dollar zero is $0 

$ ./bar 

dollar under is ./bar 
dollar zero is ./bar 

$ . ./bar 
dollar under is bar 
dollar zero is -ksh 

Avviso l'ultima riga lì? Usa $ _. Almeno in Korn. YMMV in bash, csh, et al ..

+0

Questa risposta dovrebbe essere incorporata in quella accettata. Ho faticato per mezz'ora ad acquisire il mio script ksh fino a quando ho capito che avevo bisogno di '$ _'. – andreee

0

Ho aggiornato la risposta di Edward Staudt, per essere in grado di gestire i collegamenti simbolici del percorso assoluto e anche le catene di collegamenti.

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 

brutto, ma funziona ... Dopo run questo, il percorso è di $ cPath e il file è di $ CFILE

0

Utilizzando $ _ fornisce l'ultimo comando.

>source my_script 

Opere se emette il comando due volte:

>source my_script 
>source my_script 

Se io uso una diversa sequenza di comandi:

>who 
>source my_script 

I $ _ rendimenti variabili "che"