Come determinare il percorso assoluto di un file in uno script di shell

2

Sto scrivendo uno script generico che può essere passato sia a percorsi assoluti che relativi (alla corrente directory di lavoro) ai file esistenti.

Ho bisogno di un modo sicuro per trasformare tutti quei percorsi passati in percorsi assoluti perché ho bisogno di passare i percorsi al comando "apri", che in non passerà la directory corrente all'app avviata.

Un'idea che ho avuto è di verificare se il percorso inizia con un "/", e se no, allora anteperei il percorso della directory di lavoro corrente ad esso.

Tuttavia, mi chiedo se c'è una soluzione più intelligente a questo. Inoltre, dato che sono abbastanza inesperto con gli script di shell e gli strumenti correlati, non so nemmeno come testare il valore di una variabile per iniziare con "/". Sto cercando una soluzione portatile per l'esecuzione su più Mac, quindi l'installazione di strumenti aggiuntivi o la configurazione non sarebbe l'ideale.

Qualcuno può suggerire uno script standard utilizzando solo gli strumenti di spedizione che accettano una variabile (chiamiamola $ path) e la trasforma in un percorso assoluto se non è già assoluta?

    
posta Thomas Tempelmann 14.02.2013 - 16:55
fonte

3 risposte

2

Un'opzione sarebbe installare coreutils e usare greadlink -f . Risolve i collegamenti simbolici e funziona con /Foo/ o ~/foo.txt se non esistono, ma non con /Foo/foo.txt se /Foo/ non esiste.

$ brew install coreutils
$ greadlink -f /etc
/private/etc
$ greadlink -f ~/Documents/
/Users/lauri/Documents
$ greadlink -f ..
/Users
$ greadlink -f //etc/..////
/private
$ greadlink -f /Foo
/Foo
$ greadlink -f /Foo/foo.txt
$ 

Questo non risolve i collegamenti simbolici e non funziona anche con /Foo/foo.txt .

abspath() {
  if [ -d "$1" ]; then
    ( cd "$1"; dirs -l +0 )
  else
    ( cd "$(dirname "$1")"; d=$(dirs -l +0); echo "${d%/}/${1##*/}" )
  fi
}

abspath /etc # /etc
abspath /Foo/foo.txt # doesn't work
abspath /Foo # works
abspath .
abspath ./
abspath ../
abspath ..
abspath /
abspath ~
abspath ~/
abspath ~/Documents
abspath /\"\ \'
abspath /etc/../etc/
abspath /private//etc/
abspath /private//
abspath //private # //private
abspath ./aa.txt
abspath aa.tar.gz
abspath .aa.txt
abspath /.DS_Store

dirs -l esegue l'espansione tilde. dirs +0 stampa solo la directory superiore se ci sono altre directory nello stack. Puoi anche sostituire le subshell con qualcosa come old="$PWD" ... cd "$old" .

expand_path di Ruby funziona con tutti i percorsi che non esistono, ma non risolve i collegamenti simbolici.

$ ruby -e 'print File.expand_path ARGV[0]' ~/aa/bb
/Users/lauri/aa/bb$ 
    
risposta data 14.02.2013 - 17:24
fonte
1

Non sono sicuro che questa risposta sarà abbastanza completa per le tue esigenze, ma questo è quello che farei ...

- DISCLAIMER: Non ho provato questo in SH / BASH / Anything, quindi usa questo come framework per favore. Sentiti libero di modificare la domanda dopo averla funzionante! -

Puoi verificare se l'argomento script fornito inizia con un carattere usando qualcosa come if [[ $a == "/*" ]] .

Poiché tutti i percorsi relativi portano con sé l'ipotesi che il percorso di lavoro sia la directory genitore, se sai che il percorso è non già assoluto puoi usare pwd , assumendo lo script o il processo genitore non ha cambiato la directory di lavoro .

Se il problema della modifica della directory di lavoro è significativo, dovrai utilizzare una funzione come find .

Alcune note aggiuntive che potrebbero metterti sulla giusta strada per risolvere il tuo problema: link

link

link

Spero che ti metta nella giusta direzione!

    
risposta data 14.02.2013 - 17:11
fonte
1

No - un percorso è solo una stringa e devi analizzarlo per decidere se è assoluto o relativo a $ PWD o ~

Vedi questi per più contesto nel caso in cui la mia risposta sia troppo corta.

risposta data 14.02.2013 - 17:12
fonte

Leggi altre domande sui tag