Em shells POSIX, .
é um builtin especial, então sua falha faz com que o shell saia (em alguns shells como bash
, ele é feito somente no modo POSIX).
O que se qualifica como erro depende do shell. Nem todos saem com um erro de sintaxe ao analisar o arquivo, mas a maioria sai quando o arquivo originado não pode ser encontrado ou aberto. Eu não sei de nenhum que saia se o último comando no arquivo originado retornar com um status de saída diferente de zero (a menos que a opção errexit
esteja ligada, é claro).
Aqui fazendo:
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
É um caso em que você deseja criar o arquivo se ele estiver lá e não, se não estiver (ou está vazio aqui com -s
).
Isto é, não deve ser considerado um erro (erro fatal em shells POSIX) se o arquivo não estiver lá, esse arquivo é 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 é que o shell sairá com um erro se o arquivo for removido entre o [
e o .
, mas eu diria que é válido considerá-lo um erro que esse arquivo de caminho fixo desaparecem de repente enquanto o script está sendo executado.
Por outro lado,
command . "$NVM_DIR/nvm.sh" 2> /dev/null
onde command
¹ remove o atributo especial para o comando .
(para não sair do shell em erro) não funcionaria como:
- esconderia os erros de
.
, mas também os erros dos comandos executados no arquivo de origem - também ocultaria condições reais de erro, como o arquivo com permissões erradas.
Outras sintaxes comuns (veja por exemplo grep -r /etc/default /etc/init*
nos sistemas Debian para os scripts init que ainda não foram convertidos em systemd
(onde EnvironmentFile=-/etc/default/service
é usado para especificar um arquivo de ambiente opcional)) include:
-
[ -e "$file" ] && . "$file"
Verifique se o arquivo está lá, continue a acessá-lo se estiver vazio. Ainda erro fatal se não puder ser aberto (mesmo que esteja lá ou esteja lá). Você pode ver mais variantes como
[ -f "$file" ]
(existe e é um arquivo regular ),[ -r "$file" ]
(é legível) ou combinações desses. -
[ ! -e "$file" ] || . "$file"
Uma versão ligeiramente 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 em$file
(no caso anterior, se você obtiver1
, não saberá 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 dos itens acima: tudo bem se o arquivo não estiver lá, e para os POSIX shells, falhas para abrir (ou analisar) o arquivo são reportadas, mas não são fatais (o que pode ser mais desejável para
~/.profile
). / p>
¹ Nota: Em zsh
, no entanto, você não pode usar command
, a não ser em sh
emulation; Observe que no shell Korn, source
é, na verdade, um alias para command .
, uma variante não especial de .