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$filenã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 .