Nos shells POSIX, .
é um built-in especial, portanto, sua falha faz com que o shell seja encerrado (em alguns shells bash
, isso é feito apenas no modo POSIX).
O que qualifica como um erro depende do shell. Nem todos saem com um erro de sintaxe ao analisar o arquivo, mas a maioria sai quando o arquivo de origem não pode ser encontrado ou aberto. Não conheço nenhum que sairia se o último comando no arquivo de origem retornasse com um status de saída diferente de zero (a menos que a errexit
opção esteja ativada).
Aqui fazendo:
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
É um caso em que você deseja originar o arquivo, se estiver lá, e não, se não estiver (ou estiver vazio aqui com -s
).
Ou seja, não deve ser considerado um erro (erro fatal nos shells POSIX) se o arquivo não estiver lá, esse arquivo será considerado um arquivo opcional.
Ainda seria um erro (fatal) se o arquivo não fosse legível ou fosse um diretório ou (em alguns shells) se houvesse um erro de sintaxe ao analisá-lo, o que seriam condições reais de erro que deveriam ser relatadas.
Alguns argumentam que há uma condição de corrida. Mas a única coisa que isso significa seria que o shell sairia com um erro se o arquivo fosse removido entre [
e .
, mas eu diria que é válido considerar um erro que esse arquivo de caminho fixo desapareça repentinamente enquanto o script é corrida.
Por outro lado,
command . "$NVM_DIR/nvm.sh" 2> /dev/null
em que command
¹ remove o atributo especial do .
comando (para que ele não saia do shell por erro) não funcionaria como:
- ocultaria
.
os erros, mas também os erros dos comandos executados no arquivo de origem
- também ocultaria condições de erro reais, como o arquivo com permissões erradas.
Outras sintaxes comuns (veja, por exemplo, grep -r /etc/default /etc/init*
nos sistemas Debian, os scripts init que ainda não foram convertidos systemd
(ondeEnvironmentFile=-/etc/default/service
é usado para especificar um arquivo de ambiente opcional)) incluem:
[ -e "$file" ] && . "$file"
Verifique o arquivo que está lá, ainda o fonte se estiver vazio. Ainda erro fatal se não puder ser aberto (mesmo que esteja lá ou existisse). Você pode ver mais variantes como [ -f "$file" ]
(existe e é um arquivo arquivo ), [ -r "$file" ]
(é legível) ou combinações delas.
[ ! -e "$file" ] || . "$file"
Uma versão um pouco melhor. Torna mais claro que o arquivo não existente é um caso OK. Isso também significa $?
que refletirá o status de saída do último comando executado $file
(no caso anterior, se você receber 1
, não sabe se é porque$file
não existia ou se esse comando falhou).
command . "$file"
Espere que o arquivo esteja lá, mas não saia se não puder ser interpretado.
[ ! -e "$file" ] || command . "$file"
Combinação do que foi dito acima: tudo bem se o arquivo não estiver lá e, para shells POSIX, falhas ao abrir (ou analisar) o arquivo são relatadas, mas não são fatais (o que pode ser mais desejável para ~/.profile
).
¹ Nota: No zsh
entanto, você não pode usar command
assim, a menos que seja sh
emulado; note que no shell Korn, source
na verdade é um alias para command .
, uma variante não especial de.