2016-01-26 10 views
31

Come si fa a scegliere tra "$0" e "${BASH_SOURCE[0]}"

Questa descrizione da GNU non mi ha aiutato molto.

BASH_SOURCE 

An array variable whose members are the source filenames where the 
corresponding shell function names in the FUNCNAME array variable are 
defined. The shell function ${FUNCNAME[$i]} is defined in the file 
${BASH_SOURCE[$i]} and called from ${BASH_SOURCE[$i+1]} 

risposta

45

${BASH_SOURCE[0]} (o, più semplicemente, $BASH_SOURCE[1] ) contiene il (potenzialmente relativa) percorso dello script contenente in tutti scenari di chiamata, in particolare anche quando lo script è provenienza, che non è vero per $0.

Inoltre, come Charles Duffy sottolinea, $0 può essere impostato su un valore arbitrariodal chiamante.
D'altra parte, $BASH_SOURCEpuò essere vuoto, se non è coinvolto alcun file con nome; es:
echo 'echo "[$BASH_SOURCE]"' | bash

Il seguente esempio illustra questo:

Script foo:

#!/usr/bin/env bash 
echo "[$0] vs. [${BASH_SOURCE[0]}]" 

$ bash ./foo 
[./foo] vs. [./foo] 

$ . ./foo 
[bash] vs. [./foo] 

$0 è parte della specifica shell POSIX, che BASH_SOURCE, come nome suggerisce, è specifico di Bash.


[1] lettura opzionale: ${BASH_SOURCE[0]} vs $BASH_SOURCE:

Bash permette di riferimento elemento 0 di un variabile array usando scalare notazione: invece di scrivere ${arr[0]}, si può scrivere $arr; in altre parole: se si fa riferimento alla variabile come se fosse uno scalare, si ottiene l'elemento all'indice 0.

Utilizzando questa funzione oscura il fatto che $arr è un array, ed è per questo popolare shell-codice linter shellcheck.net emette il seguente avviso (al momento della scrittura):

SC2128: Espansione di un array senza indice dà solo il primo elemento.

Su un lato nota: Anche se questo avviso è utile, potrebbe essere più preciso, perché non sarà necessariamente ottenere il primo elemento : E 'specificamente l'elemento in corrispondenza dell'indice 0 che viene restituito, quindi se il primo elemento ha un indice più alto - che è possibile in Bash - otterrai la stringa vuota; prova 'a[1]='hi'; echo "$a"'.
(Al contrario, zsh, mai il rinnegato, infatti fa restituisce il primo elemento, indipendentemente dal suo indice).

Si può scegliere di astenersi questa funzione a causa della sua oscurità, ma funziona in modo prevedibile e, pragmaticamente parlando, ti raramente, se mai, bisogno di accedere indici altri di 0 della variabile di matrice ${BASH_SOURCE[@]}.

+1

* "... o, più semplicemente,' $ BASH_SOURCE' ... "* - uomo, questo si accende a shellcheck.net come un albero di Natale. Evita '$ BASH_SOURCE' ... – jww

+4

" (o, più semplicemente, '$ BASH_SOURCE')" ← ** No, per favore non farlo. ** '$ BASH_SOURCE' è un array globale - * non * uno scalare globale. Costringere silenziosamente il primo nel secondo è garantito fallire per casi limite comuni. Per sicurezza, * sempre * accedere a specifici indici di array di '$ BASH_SOURCE' (ad esempio,' $ {BASH_SOURCE [0]} '). –

+1

@CecilCurry: vedere la nota a piè di pagina che ho aggiunto. Ho capito che l'accesso scalare è _obscure_, ma non sono a conoscenza di scenari in cui _fails_. – mklement0