Nelle shell POSIX, .
è un builtin speciale, quindi il suo errore provoca l'uscita della shell (in alcune shell come bash
, viene eseguita solo in modalità POSIX).
Ciò che si qualifica come errore dipende dalla shell. Non tutti escono in seguito a un errore di sintassi durante l'analisi del file, ma la maggior parte terminerebbe quando non è possibile trovare o aprire il file di origine. Non conosco alcuno che uscirebbe se l'ultimo comando nel file di origine restituisse con uno stato di uscita diverso da zero (a meno che l' errexit
opzione non sia attiva, ovviamente).
Qui facendo:
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
È un caso in cui si desidera estrarre il file se è presente e non farlo se non lo è (o è vuoto qui con -s
).
Cioè, non dovrebbe essere considerato un errore (errore fatale nelle shell POSIX) se il file non è presente, quel file è considerato un file opzionale.
Sarebbe comunque un errore (fatale) se il file non fosse leggibile o fosse una directory o (in alcune shell) se si fosse verificato un errore di sintassi durante l'analisi che sarebbe condizioni di errore reali che dovrebbero essere segnalate.
Alcuni sosterrebbero che esiste una condizione di razza. Ma l'unica cosa che significherebbe sarebbe che la shell sarebbe uscita con un errore se il file fosse rimosso tra il [
e .
, ma direi che è valido considerarlo un errore che questo file a percorso fisso svanirebbe improvvisamente mentre lo script è in esecuzione.
D'altro canto,
command . "$NVM_DIR/nvm.sh" 2> /dev/null
dove command
¹ rimuove l' attributo speciale dal .
comando (quindi non esce dalla shell in caso di errore) non funzionerebbe come:
- nasconderebbe
.
gli errori ma anche gli errori dei comandi eseguiti nel file di origine
- nasconderebbe anche condizioni di errore reali come il file con autorizzazioni errate.
Altre sintassi comuni (vedere ad esempio grep -r /etc/default /etc/init*
sui sistemi Debian per gli script di init che non sono stati systemd
ancora convertiti (dove invece EnvironmentFile=-/etc/default/service
viene usato per specificare un file di ambiente opzionale)) includono:
[ -e "$file" ] && . "$file"
Controlla che il file sia lì, procedi ancora se è vuoto. Errore fatale se non può essere aperto (anche se è lì o era lì). Potresti vedere più varianti come [ -f "$file" ]
(esiste ed è un file normale ), [ -r "$file" ]
(è leggibile) o combinazioni di quelle.
[ ! -e "$file" ] || . "$file"
Una versione leggermente migliore. Rende più chiaro che il file inesistente è un caso OK. Ciò significa anche $?
che rifletterà lo stato di uscita dell'ultimo comando eseguito $file
(nel caso precedente, se ottieni 1
, non sai se è perché $file
non esisteva o se quel comando falliva).
command . "$file"
Aspettati che il file sia lì, ma non uscire se non può essere interpretato.
[ ! -e "$file" ] || command . "$file"
Combinazione di quanto sopra: va bene se il file non è presente e, per le shell POSIX, vengono segnalati errori nell'apertura (o nell'analisi) del file ma non sono fatali (per cui potrebbe essere più desiderabile ~/.profile
).
¹ Nota: zsh
tuttavia, non è possibile utilizzare in command
questo modo se non in sh
emulazione; nota che nella shell Korn, in source
realtà è un alias per command .
, una variante non speciale di.