Come posso recuperare il nome file assoluto in uno script shell su Mac OS X?


19

Vorrei recuperare il nome file assoluto del file di script attualmente eseguito. Anche i collegamenti dovrebbero essere risolti.

Su Linux, questo sembra essere fatto in questo modo:

$(readlink -mn "$0")

ma readlinksembra funzionare in modo molto diverso su Mac OS X.

Ho letto che questo è fatto usando

$(realpath $0)

in BSD ma non funziona neanche. Mac OS X non ha realpath.

Qualche idea?


1
Leggi questa domanda su SO: stackoverflow.com/questions/799679/…
Telemaco,


Risposte:


19

Imbroglio e uso perl proprio per questa cosa:

#!/bin/bash
dirname=`perl -e 'use Cwd "abs_path";print abs_path(shift)' $0`
echo $dirname

Penseresti di scrivere l'intera sceneggiatura in perl, e spesso lo faccio, ma non sempre.


Questo funziona, grazie mille. Ti darò un voto il prima possibile. Qualcuno ha un modo "puro guscio" per farlo?
Huxi,

1
Temo che questo sia il massimo. (Dati i molti hack di "pure shell" su più righe che si possono trovare su Google.)
Arjan,

un'altra possibilità (anche se brutta) è quella di attraversare il percorso '..', memorizzando (attraverso la ricorsione o un array) fino a quando '..' restituisce lo stesso file che hai appena avuto (cioè: sei in cima), quindi ritorna assemblando il percorso mentre vai. Ho visto il software di backup Networker di Legato fare questo durante lo strace come metodo per ottenere un percorso "vero" (ma forse non assoluto). Ma sarebbe molto più codice di quanto sopra.
ericslaw,

Non sono sicuro del motivo per cui qualcuno ha modificato il codice per utilizzare $ 1 anziché $ 0. $ 1 non è il primo argomento dello script bash? Volevo il percorso dello script bash in esecuzione, non è il primo argomento.
ericslaw,

27
#!/usr/bin/env bash
scriptDir="$(cd "$(dirname "$0")" && pwd -P)"

Funziona anche con MacOSX.
Alexar,

1
Questo è super! Ci sono molte altre risposte troppo complicate che fluttuano intorno.
Jason S,

3
Funziona solo con i file in una directory con link simbolici, non con i file con link simbolici in generale
Gerhard Burger

1
È anche utile unset -v CDPATHprima del cd poiché cd può generare output indesiderati se è impostato CDPATH.
File binario

Per gestire almeno un singolo livello di collegamento simbolico del file, puoi anche testare in modo compatibile con readlink (i mac non hanno -f): scriptDir=$(unset -v CDPATH; cd "$(dirname "$(readlink "$BASH_SOURCE" || echo "$BASH_SOURCE)")" && pwd -P)
File binario

0

Gestisce combinazioni di collegamenti simbolici e funziona su file e cartelle:

#!/usr/bin/env bash
realpath()
{
    if ! pushd $1 &> /dev/null; then 
        pushd ${1##*/} &> /dev/null
        echo $( pwd -P )/${1%/*}
    else
        pwd -P
    fi
    popd > /dev/null
}

Ma non supporta realpath's --relative-to. Ciò richiederebbe la conversione descritta qui .


0

Un altro approccio:

# Install.
brew install coreutils

# Use the GNU variant.
grealpath --help
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.