Riferimento a un file relativo all'esecuzione dello script


94

In uno script bash che sto scrivendo, utilizzo sourceper includere la variabile definita in un file di configurazione. Lo script da eseguire è act.sh, mentre lo script da eseguire sourceè act.conf.sh, quindi in act.shho:

source act.conf.sh

Tuttavia questo funziona solo quando è in esecuzione act.shnella directory che lo contiene, poiché act.conf.shsi riferisce al file posizionato sotto la directory di lavoro. Esiste una soluzione per fare in modo che si riferisca al file relativo allo script in esecuzione senza richiamarlo cd? Grazie.

Risposte:


116

Vedi: BASH FAQ entry # 28: "Come determino la posizione del mio script? Voglio leggere alcuni file di configurazione dalla stessa posizione."

Qualsiasi soluzione non funzionerà il 100% delle volte:

È importante rendersi conto che nel caso generale questo problema non ha soluzione. Qualsiasi approccio di cui potresti aver sentito parlare e qualsiasi approccio che verrà descritto in dettaglio di seguito, presenta difetti e funzionerà solo in casi specifici. Innanzitutto, cerca di evitare completamente il problema non dipendendo dalla posizione del tuo script!

Se hai bisogno di scrivere uno strumento molto riutilizzabile, prendere il percorso corretto come parametro dello script sarà il metodo più affidabile .

Supponendo che il tuo script verrà eseguito solo da alcune shell e solo con un po 'di flessibilità richiesta, puoi probabilmente rilassare un po' di questa paranoia. È ancora utile esaminare le tue opzioni. Ci sono modelli comuni che le persone usano che sono particolarmente problematici.

In particolare, la FAQ consiglia di evitare la $0variabile molto comunemente usata :

Niente di ciò che legge $0sarà mai a prova di proiettile, perché di per $0sé è inaffidabile.

In alternativa, potresti usare $BASH_SOURCEinvece. Qualcosa come questo:

source "${BASH_SOURCE%/*}/act.conf.sh"

Ci sono anche alcuni avvertimenti su questa soluzione. Consulta la pagina delle domande frequenti per vedere i compromessi tra le diverse soluzioni. Sembrano consigliare cdin combinazione con $BASH_SOURCEnei casi in cui funzionerà per te, poiché ottieni una pratica condizione di errore quando non si espande correttamente.


1
Grazie, userei readlink. Non sono stato in grado di determinare le parole chiave da cercare, quindi ho postato la domanda qui ....
Ryan Li

9
Puoi inserire le informazioni pertinenti nella risposta nel caso in cui la faq di bash non sia disponibile?
Merlyn Morgan-Graham

3
Link consiglia:, cd "${BASH_SOURCE%/*}" || exito read somevar < "${BASH_SOURCE%/*}/etc/somefile", Link fortemente scoraggia $0 "Niente di quello che legge $ 0 sarà mai a prova di proiettile, perché $ 0 stesso è inaffidabile."
ThorSummoner

10
Cosa fa il% / * dopo BASH_SOURCE e come?
Silicomancer



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.