Ottieni la directory sorgente di uno script Bash dall'interno dello script stesso

StackOverflow https://stackoverflow.com/questions/59895

  •  09-06-2019
  •  | 
  •  

Domanda

Come posso ottenere il percorso della directory in cui a Bash si trova lo script, dentro quella sceneggiatura?

Ad esempio, diciamo che voglio utilizzare uno script Bash come launcher per un'altra applicazione.Voglio cambiare la directory di lavoro in quella in cui si trova lo script Bash, così posso operare sui file in quella directory, in questo modo:

$ ./application
È stato utile?

Soluzione

#!/bin/bash

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"

è un utile one-liner che ti darà il nome completo della directory dello script, indipendentemente da dove viene chiamato.

Funzionerà finché l'ultimo componente del percorso utilizzato per trovare lo script non è un collegamento simbolico (i collegamenti alle directory sono OK).Se vuoi risolvere anche eventuali collegamenti allo script stesso, hai bisogno di una soluzione multilinea:

#!/bin/bash

SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
  DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
  SOURCE="$(readlink "$SOURCE")"
  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"

Quest'ultimo funzionerà con qualsiasi combinazione di alias, source, bash -c, collegamenti simbolici, ecc.

Attenzione:se tu cd in una directory diversa prima di eseguire questo snippet, il risultato potrebbe essere errato!

Inoltre, fai attenzione $CDPATH trabocchetti, e effetti collaterali sull'output di stderr se l'utente ha sovrascritto in modo intelligente cd per reindirizzare invece l'output su stderr (incluse le sequenze di escape, come quando si chiama update_terminal_cwd >&2 su Mac).Aggiunta >/dev/null 2>&1 alla fine del tuo cd il comando si occuperà di entrambe le possibilità.

Per capire come funziona, prova a eseguire questo modulo più dettagliato:

#!/bin/bash

SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
  TARGET="$(readlink "$SOURCE")"
  if [[ $TARGET == /* ]]; then
    echo "SOURCE '$SOURCE' is an absolute symlink to '$TARGET'"
    SOURCE="$TARGET"
  else
    DIR="$( dirname "$SOURCE" )"
    echo "SOURCE '$SOURCE' is a relative symlink to '$TARGET' (relative to '$DIR')"
    SOURCE="$DIR/$TARGET" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
  fi
done
echo "SOURCE is '$SOURCE'"
RDIR="$( dirname "$SOURCE" )"
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
if [ "$DIR" != "$RDIR" ]; then
  echo "DIR '$RDIR' resolves to '$DIR'"
fi
echo "DIR is '$DIR'"

E stamperà qualcosa come:

SOURCE './scriptdir.sh' is a relative symlink to 'sym2/scriptdir.sh' (relative to '.')
SOURCE is './sym2/scriptdir.sh'
DIR './sym2' resolves to '/home/ubuntu/dotfiles/fo fo/real/real1/real2'
DIR is '/home/ubuntu/dotfiles/fo fo/real/real1/real2'

Altri suggerimenti

Utilizzo dirname "$0":

#!/bin/bash
echo "The script you are running has basename `basename "$0"`, dirname `dirname "$0"`"
echo "The present working directory is `pwd`"

utilizzando pwd da solo non funzionerà se non stai eseguendo lo script dalla directory in cui è contenuto.

[matt@server1 ~]$ pwd
/home/matt
[matt@server1 ~]$ ./test2.sh
The script you are running has basename test2.sh, dirname .
The present working directory is /home/matt
[matt@server1 ~]$ cd /tmp
[matt@server1 tmp]$ ~/test2.sh
The script you are running has basename test2.sh, dirname /home/matt
The present working directory is /tmp

Il comando dirname è il più semplice, analizza semplicemente il percorso fino al nome del file dalla variabile $0 (nome script):

dirname "$0"

Ma come opaco B sottolineato, il percorso restituito è diverso a seconda di come viene chiamato lo script.pwd non fa il lavoro perché ti dice solo qual è la directory corrente, non in quale directory risiede lo script.Inoltre, se viene eseguito un collegamento simbolico a uno script, otterrai un percorso (probabilmente relativo) in cui risiede il collegamento, non lo script vero e proprio.

Alcuni altri hanno menzionato il leggerelink comando, ma nella sua forma più semplice, puoi usare:

dirname "$(readlink -f "$0")"

readlink risolverà il percorso dello script in un percorso assoluto dalla radice del filesystem.Pertanto, qualsiasi percorso contenente punti singoli o doppi, tilde e/o collegamenti simbolici verrà risolto in un percorso completo.

Ecco uno script che dimostra ciascuno di questi, whatdir.sh:

#!/bin/bash
echo "pwd: `pwd`"
echo "\$0: $0"
echo "basename: `basename $0`"
echo "dirname: `dirname $0`"
echo "dirname/readlink: $(dirname $(readlink -f $0))"

Eseguendo questo script nella mia directory home, utilizzando un percorso relativo:

>>>$ ./whatdir.sh 
pwd: /Users/phatblat
$0: ./whatdir.sh
basename: whatdir.sh
dirname: .
dirname/readlink: /Users/phatblat

Ancora una volta, ma utilizzando il percorso completo dello script:

>>>$ /Users/phatblat/whatdir.sh 
pwd: /Users/phatblat
$0: /Users/phatblat/whatdir.sh
basename: whatdir.sh
dirname: /Users/phatblat
dirname/readlink: /Users/phatblat

Ora cambio directory:

>>>$ cd /tmp
>>>$ ~/whatdir.sh 
pwd: /tmp
$0: /Users/phatblat/whatdir.sh
basename: whatdir.sh
dirname: /Users/phatblat
dirname/readlink: /Users/phatblat

E infine utilizzando un collegamento simbolico per eseguire lo script:

>>>$ ln -s ~/whatdir.sh whatdirlink.sh
>>>$ ./whatdirlink.sh 
pwd: /tmp
$0: ./whatdirlink.sh
basename: whatdirlink.sh
dirname: .
dirname/readlink: /Users/phatblat
pushd . > /dev/null
SCRIPT_PATH="${BASH_SOURCE[0]}"
if ([ -h "${SCRIPT_PATH}" ]); then
  while([ -h "${SCRIPT_PATH}" ]); do cd `dirname "$SCRIPT_PATH"`; 
  SCRIPT_PATH=`readlink "${SCRIPT_PATH}"`; done
fi
cd `dirname ${SCRIPT_PATH}` > /dev/null
SCRIPT_PATH=`pwd`;
popd  > /dev/null

Funziona per tutte le versioni, incluse

  • quando chiamato tramite soft link a più profondità,
  • quando lo file
  • quando lo script viene chiamato dal comando "source"ovvero . (punto) operatore.
  • quando arg $0 viene modificato dal chiamante.
  • "./script"
  • "/full/path/to/script"
  • "/some/path/../../another/path/script"
  • "./some/folder/script"

In alternativa, se lo script bash stesso è un file collegamento simbolico relativo Voi Volere per seguirlo e restituire il percorso completo dello script collegato:

pushd . > /dev/null
SCRIPT_PATH="${BASH_SOURCE[0]}";
if ([ -h "${SCRIPT_PATH}" ]) then
  while([ -h "${SCRIPT_PATH}" ]) do cd `dirname "$SCRIPT_PATH"`; SCRIPT_PATH=`readlink "${SCRIPT_PATH}"`; done
fi
cd `dirname ${SCRIPT_PATH}` > /dev/null
SCRIPT_PATH=`pwd`;
popd  > /dev/null

SCRIPT_PATH viene fornito per intero, indipendentemente da come viene chiamato.
Assicurati solo di individuarlo all'inizio dello script.

Questo commento e codice Copyleft, licenza selezionabile sotto GPL2.0 o successiva o CC-SA 3.0 (CreativeCommons Share Alike) o successiva.c) 2008.Tutti i diritti riservati.Nessuna garanzia di alcun tipo.Sei stato avvertito.
http://www.gnu.org/licenses/gpl-2.0.txt
http://creativecommons.org/licenses/by-sa/3.0/
18eedfe1c99df68dc94d4a94712a71aaa8e1e9e36cacf421b9463dd2bbaa02906d0d6656

Risposta breve:

`dirname $0`

O (preferibilmente):

$(dirname "$0")

Puoi utilizzare $BASH_SOURCE

#!/bin/bash

scriptdir=`dirname "$BASH_SOURCE"`

Tieni presente che devi usare #!/bin/bash e non #!/bin/sh poiché è un'estensione bash

Questo dovrebbe farlo:

DIR=$(dirname "$(readlink -f "$0")")

Funziona con collegamenti simbolici e spazi nel percorso.Vedi le pagine man per nome E leggerelink.

Modificare:

Dalla traccia dei commenti sembra che non funzioni con Mac OS.Non ho idea del perché.Eventuali suggerimenti?

pwd può essere utilizzato per trovare la directory di lavoro corrente e dirname per trovare la directory di un particolare file (il comando eseguito è $0, COSÌ dirname $0 dovrebbe darti la directory dello script corrente).

Tuttavia, dirname fornisce esattamente la parte directory del nome file, che molto probabilmente sarà relativa alla directory di lavoro corrente.Se il tuo script deve cambiare directory per qualche motivo, l'output di dirname diventa privo di significato.

Suggerisco quanto segue:

#!/bin/bash

reldir=`dirname $0`
cd $reldir
directory=`pwd`

echo "Directory is $directory"

In questo modo, ottieni una directory assoluta, anziché relativa.

Poiché lo script verrà eseguito in un'istanza bash separata, non è necessario ripristinare successivamente la directory di lavoro, ma se per qualche motivo desideri tornare allo script, puoi facilmente assegnare il valore di pwd in una variabile prima di cambiare directory, per uso futuro.

Anche se giusto

cd `dirname $0`

risolve lo scenario specifico nella domanda, trovo che avere il percorso assoluto sia più utile in generale.

Non penso che sia così facile come altri hanno pensato che fosse.pwd non funziona, poiché la directory corrente non è necessariamente la directory con lo script.Anche $ 0 non ha sempre le informazioni.Considera i tre modi seguenti per richiamare uno script.

./script

/usr/bin/script

script

Nel primo e nel terzo modo $ 0 non ha le informazioni sul percorso completo.Nel secondo e nel terzo, pwd non funziona.L'unico modo per ottenere la directory nel terzo modo sarebbe percorrere il percorso e trovare il file con la corrispondenza corretta.Fondamentalmente il codice dovrebbe ripetere ciò che fa il sistema operativo.

Un modo per fare ciò che stai chiedendo sarebbe semplicemente codificare i dati nella directory /usr/share e farvi riferimento tramite il percorso completo.I dati non dovrebbero comunque trovarsi nella directory /usr/bin, quindi questa è probabilmente la cosa da fare.

SCRIPT_DIR=$( cd ${0%/*} && pwd -P )

Questo ottiene la directory di lavoro corrente su Mac OS X 10.6.6:

DIR=$(cd "$(dirname "$0")"; pwd)
$(dirname "$(readlink -f "$BASH_SOURCE")")

Sono stanco di tornare su questa pagina più e più volte per copiare e incollare la riga nella risposta accettata.Il problema è che non è facile da capire e ricordare.

Ecco uno script facile da ricordare:

DIR=$(dirname "${BASH_SOURCE[0]}")  # get the directory name
DIR=$(realpath "${DIR}")    # resolve its full path if need be

Questo è specifico per Linux, ma potresti usare:

SELF=$(readlink /proc/$$/fd/255)

Ecco una riga conforme a POSIX:

SCRIPT_PATH=`dirname "$0"`; SCRIPT_PATH=`eval "cd \"$SCRIPT_PATH\" && pwd"`

# test
echo $SCRIPT_PATH

Ho provato ognuno di questi e nessuno di loro ha funzionato.Uno era molto vicino ma aveva un piccolo insetto che lo ruppe gravemente;si sono dimenticati di racchiudere il percorso tra virgolette.

Inoltre, molte persone presumono che tu stia eseguendo lo script da una shell, quindi dimentica che quando apri un nuovo script, per impostazione predefinita viene impostato a casa tua.

Prova questa directory per dimensioni:

/var/Nessuno/Pensato/Sugli spazi presenti/In una directory/Nome/Ed ecco il tuo file.text

Questo funziona correttamente indipendentemente da come o dove lo esegui.

#!/bin/bash
echo "pwd: `pwd`"
echo "\$0: $0"
echo "basename: `basename "$0"`"
echo "dirname: `dirname "$0"`"

Quindi, per renderlo davvero utile, ecco come passare alla directory dello script in esecuzione:

cd "`dirname "$0"`"

Spero possa aiutare

Ecco il modo semplice e corretto:

actual_path=$(readlink -f "${BASH_SOURCE[0]}")
script_dir=$(dirname "$actual_path")

Spiegazione:

  • ${BASH_SOURCE[0]} - il percorso completo dello script.Il valore di questo sarà corretto anche quando viene generato lo script, ad es. source <(echo 'echo $0') stampe bash, sostituendolo con ${BASH_SOURCE[0]} stamperà il percorso completo dello script.(Ovviamente, questo presuppone che tu stia bene prendendo una dipendenza da Bash.)

  • readlink -f - Risolve ricorsivamente tutti i collegamenti simbolici nel percorso specificato.Questa è un'estensione GNU e non è disponibile (ad esempio) sui sistemi BSD.Se utilizzi un Mac, puoi utilizzare Homebrew per installare GNU coreutils e sostituirlo con greadlink -f.

  • E naturalmente dirname ottiene la directory principale del percorso.

Vorrei usare qualcosa del genere:

# retrieve the full pathname of the called script
scriptPath=$(which $0)

# check whether the path is a link or not
if [ -L $scriptPath ]; then

    # it is a link then retrieve the target path and get the directory name
    sourceDir=$(dirname $(readlink -f $scriptPath))

else

    # otherwise just get the directory name of the script path
    sourceDir=$(dirname $scriptPath)

fi

Una leggera revisione alla soluzione e-satis e 3bcdnlklvc04a segnalata in la loro risposta

SCRIPT_DIR=''
pushd "$(dirname "$(readlink -f "$BASH_SOURCE")")" > /dev/null && {
    SCRIPT_DIR="$PWD"
    popd > /dev/null
}    

Questo dovrebbe funzionare ancora in tutti i casi elencati.

MODIFICARE:previene il popd dopo un push fallito, grazie a konsolebox

#!/bin/sh
PRG="$0"

# need this for relative symlinks
while [ -h "$PRG" ] ; do
   PRG=`readlink "$PRG"`
done

scriptdir=`dirname "$PRG"`

$_ vale la pena menzionare come alternativa a $ 0.Se stai eseguendo uno script da bash, la risposta accettata può essere abbreviata in:

DIR="$( dirname "$_" )"

Tieni presente che questa deve essere la prima istruzione nel tuo script.

Ho confrontato molte delle risposte fornite e ho trovato alcune soluzioni più compatte.Questi sembrano gestire tutti i casi limite folli che derivano dalla tua combinazione preferita di:

  • Percorsi assoluti o percorsi relativi
  • Collegamenti software a file e directory
  • Invocazione come script, bash script, bash -c script, source script, O . script
  • Spazi, tabulazioni, fine riga, unicode, ecc.nelle directory e/o nel nome del file
  • Nomi di file che iniziano con un trattino

Se utilizzi Linux, sembra che utilizzando il file proc handle è la soluzione migliore per individuare l'origine completamente risolta dello script attualmente in esecuzione (in una sessione interattiva, il collegamento punta al rispettivo /dev/pts/X):

resolved="$(readlink /proc/$$/fd/255 && echo X)" && resolved="${resolved%$'\nX'}"

Questo ha un po' di bruttezza, ma la soluzione è compatta e facile da capire.Non stiamo usando solo le primitive bash, ma mi va bene perché readlink semplifica notevolmente il compito.IL echo X aggiunge un X alla fine della variabile stringa in modo che eventuali spazi bianchi finali nel nome del file non vengano mangiati e la sostituzione del parametro ${VAR%X} alla fine della riga si elimina il X.Perché readlink aggiunge un proprio ritorno a capo (che normalmente verrebbe mangiato nella sostituzione del comando se non fosse per il nostro precedente inganno), dobbiamo eliminare anche quello.Questo è più facilmente realizzabile utilizzando il file $'' schema di virgolette, che ci consente di utilizzare sequenze di escape come \n per rappresentare i ritorni a capo (questo è anche il modo in cui puoi facilmente creare directory e file con nomi ambigui).

Quanto sopra dovrebbe coprire le tue esigenze per individuare lo script attualmente in esecuzione su Linux, ma se non hai il file proc filesystem a tua disposizione o se stai cercando di individuare il percorso completamente risolto di qualche altro file, forse troverai utile il codice seguente.È solo una leggera modifica rispetto alla frase precedente.Se stai giocando con nomi di directory/file strani, controlla l'output con entrambi ls E readlink è informativo, come ls genererà percorsi "semplificati", sostituendo ? per cose come le nuove righe.

absolute_path=$(readlink -e -- "${BASH_SOURCE[0]}" && echo x) && absolute_path=${absolute_path%?x}
dir=$(dirname -- "$absolute_path" && echo x) && dir=${dir%?x}
file=$(basename -- "$absolute_path" && echo x) && file=${file%?x}

ls -l -- "$dir/$file"
printf '$absolute_path: "%s"\n' "$absolute_path"

Prova a utilizzare:

real=$(realpath $(dirname $0))

Per i sistemi dotati di coreutils GNU readlink (ad es.Linux):

$(readlink -f "$(dirname "$0")")

Non è necessario utilizzarlo BASH_SOURCE Quando $0 contiene il nome del file dello script.

COSÌ...Credo di avere questo.Tardi per la festa, ma penso che alcuni apprezzeranno il fatto di essere qui se si imbattono in questo thread.I commenti dovrebbero spiegare.

#!/bin/sh # dash bash ksh # !zsh (issues). G. Nixon, 12/2013. Public domain.

## 'linkread' or 'fullpath' or (you choose) is a little tool to recursively
## dereference symbolic links (ala 'readlink') until the originating file
## is found. This is effectively the same function provided in stdlib.h as
## 'realpath' and on the command line in GNU 'readlink -f'.

## Neither of these tools, however, are particularly accessible on the many
## systems that do not have the GNU implementation of readlink, nor ship
## with a system compiler (not to mention the requisite knowledge of C).

## This script is written with portability and (to the extent possible, speed)
## in mind, hence the use of printf for echo and case statements where they
## can be substituded for test, though I've had to scale back a bit on that.

## It is (to the best of my knowledge) written in standard POSIX shell, and
## has been tested with bash-as-bin-sh, dash, and ksh93. zsh seems to have
## issues with it, though I'm not sure why; so probably best to avoid for now.

## Particularly useful (in fact, the reason I wrote this) is the fact that
## it can be used within a shell script to find the path of the script itself.
## (I am sure the shell knows this already; but most likely for the sake of
## security it is not made readily available. The implementation of "$0"
## specificies that the $0 must be the location of **last** symbolic link in
## a chain, or wherever it resides in the path.) This can be used for some
## ...interesting things, like self-duplicating and self-modifiying scripts.

## Currently supported are three errors: whether the file specified exists
## (ala ENOENT), whether its target exists/is accessible; and the special
## case of when a sybolic link references itself "foo -> foo": a common error
## for beginners, since 'ln' does not produce an error if the order of link
## and target are reversed on the command line. (See POSIX signal ELOOP.)

## It would probably be rather simple to write to use this as a basis for
## a pure shell implementation of the 'symlinks' util included with Linux.

## As an aside, the amount of code below **completely** belies the amount
## effort it took to get this right -- but I guess that's coding for you.

##===-------------------------------------------------------------------===##

for argv; do :; done # Last parameter on command line, for options parsing.

## Error messages. Use functions so that we can sub in when the error occurs.

recurses(){ printf "Self-referential:\n\t$argv ->\n\t$argv\n" ;}
dangling(){ printf "Broken symlink:\n\t$argv ->\n\t"$(readlink "$argv")"\n" ;}
errnoent(){ printf "No such file: "$@"\n" ;} # Borrow a horrible signal name.

# Probably best not to install as 'pathfull', if you can avoid it.

pathfull(){ cd "$(dirname "$@")"; link="$(readlink "$(basename "$@")")"

## 'test and 'ls' report different status for bad symlinks, so we use this.

 if [ ! -e "$@" ]; then if $(ls -d "$@" 2>/dev/null) 2>/dev/null;  then
    errnoent 1>&2; exit 1; elif [ ! -e "$@" -a "$link" = "$@" ];   then
    recurses 1>&2; exit 1; elif [ ! -e "$@" ] && [ ! -z "$link" ]; then
    dangling 1>&2; exit 1; fi
 fi

## Not a link, but there might be one in the path, so 'cd' and 'pwd'.

 if [ -z "$link" ]; then if [ "$(dirname "$@" | cut -c1)" = '/' ]; then
   printf "$@\n"; exit 0; else printf "$(pwd)/$(basename "$@")\n"; fi; exit 0
 fi

## Walk the symlinks back to the origin. Calls itself recursivly as needed.

 while [ "$link" ]; do
   cd "$(dirname "$link")"; newlink="$(readlink "$(basename "$link")")"
   case "$newlink" in
    "$link") dangling 1>&2 && exit 1                                       ;;
         '') printf "$(pwd)/$(basename "$link")\n"; exit 0                 ;;
          *) link="$newlink" && pathfull "$link"                           ;;
   esac
 done
 printf "$(pwd)/$(basename "$newlink")\n"
}

## Demo. Install somewhere deep in the filesystem, then symlink somewhere 
## else, symlink again (maybe with a different name) elsewhere, and link
## back into the directory you started in (or something.) The absolute path
## of the script will always be reported in the usage, along with "$0".

if [ -z "$argv" ]; then scriptname="$(pathfull "$0")"

# Yay ANSI l33t codes! Fancy.
 printf "\n\033[3mfrom/as: \033[4m$0\033[0m\n\n\033[1mUSAGE:\033[0m   "
 printf "\033[4m$scriptname\033[24m [ link | file | dir ]\n\n         "
 printf "Recursive readlink for the authoritative file, symlink after "
 printf "symlink.\n\n\n         \033[4m$scriptname\033[24m\n\n        "
 printf " From within an invocation of a script, locate the script's "
 printf "own file\n         (no matter where it has been linked or "
 printf "from where it is being called).\n\n"

else pathfull "$@"
fi

Prova la seguente soluzione multicompatibile:

CWD="$(cd -P -- "$(dirname -- "$0")" && pwd -P)"

COME realpath O readlink i comandi non sono sempre disponibili (a seconda del sistema operativo) e ${BASH_SOURCE[0]} è disponibile solo nella shell bash.

In alternativa puoi provare la seguente funzione in bash:

realpath () {
  [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
}

Questa funzione accetta 1 argomento.Se l'argomento ha già un percorso assoluto, stampalo così com'è, altrimenti stampa $PWD variabile + argomento nome file (senza ./ prefisso).

Imparentato:

Hmm, se nel percorso Basename e Dirname non lo taglieranno e camminare sul sentiero è difficile (cosa se il genitore non esportava il percorso!).Tuttavia, la shell deve avere una maniglia aperta per la sua sceneggiatura e in Bash la maniglia è #255.

SELF=`readlink /proc/$$/fd/255`

per me va bene.

Per riassumere molte risposte:

    Script: "/tmp/src dir/test.sh"
    Calling folder: "/tmp/src dir/other"

Comandi utilizzati

    echo Script-Dir : `dirname "$(realpath $0)"`
    echo Script-Dir : $( cd ${0%/*} && pwd -P )
    echo Script-Dir : $(dirname "$(readlink -f "$0")")
    echo
    echo Script-Name : `basename "$(realpath $0)"`
    echo Script-Name : `basename $0`
    echo
    echo Script-Dir-Relative : `dirname "$BASH_SOURCE"`
    echo Script-Dir-Relative : `dirname $0`
    echo
    echo Calling-Dir : `pwd`

Il risultato:

     Script-Dir : /tmp/src dir
     Script-Dir : /tmp/src dir
     Script-Dir : /tmp/src dir

     Script-Name : test.sh
     Script-Name : test.sh

     Script-Dir-Relative : ..
     Script-Dir-Relative : ..

     Calling-Dir : /tmp/src dir/other

Vederehttps://pastebin.com/J8KjxrPF

Funziona in bash-3.2:

path="$( dirname "$( which "$0" )" )"

Ecco un esempio del suo utilizzo:

Diciamo che hai un ~/bin directory, che è nel tuo $PERCORSO.Hai una sceneggiatura UN all'interno di questa directory.Esso fontela sceneggiatura ~/bin/lib/B.Sai dove si trova lo script incluso rispetto a quello originale (la sottodirectory lib), ma non dove si trova rispetto alla directory corrente dell'utente.

Questo viene risolto nel modo seguente (dentro UN):

source "$( dirname "$( which "$0" )" )/lib/B"

Non importa dove si trova l'utente o come chiama lo script, funzionerà sempre.

Nessuno di questi ha funzionato per uno script bash lanciato da Finder in OS X: ho finito per utilizzare:

SCRIPT_LOC="`ps -p $$ | sed /PID/d | sed s:.*/Network/:/Network/: |
sed s:.*/Volumes/:/Volumes/:`"

Non carino, ma fa il suo lavoro.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top