En los shells POSIX, .
es un componente integrado especial, por lo que su falla hace que el shell salga (en algunos shells como bash
, solo se hace cuando está en modo POSIX).
Lo que califica como error depende del shell. No todos salen con un error de sintaxis al analizar el archivo, pero la mayoría se cierra cuando no se puede encontrar o abrir el archivo de origen. No conozco ninguno que salga si el último comando en el archivo de origen regresa con un estado de salida distinto de cero (a menos que la errexit
opción esté activada, por supuesto).
Aquí haciendo:
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
Es un caso en el que desea obtener el archivo si está allí, y no si no está (o está vacío aquí con -s
).
Es decir, no debe considerarse un error (error grave en shells POSIX) si el archivo no está allí, ese archivo se considera un archivo opcional.
Seguiría siendo un error (fatal) si el archivo no fuera legible o si fuera un directorio o (en algunos shells) si hubiera un error de sintaxis al analizarlo, que serían condiciones de error reales que deberían informarse.
Algunos dirían que hay una condición de carrera. Pero lo único que significa sería que el shell saldría con un error si el archivo se elimina entre el [
y .
, pero diría que es válido considerar que es un error que este archivo de ruta fija desaparezca repentinamente mientras el script está corriendo.
Por otra parte,
command . "$NVM_DIR/nvm.sh" 2> /dev/null
donde command
¹ elimina el atributo especial del .
comando (para que no salga del shell por error) no funcionaría como:
- ocultaría
.
los errores pero también los errores de los comandos ejecutados en el archivo de origen
- también ocultaría condiciones de error reales como que el archivo tenga los permisos incorrectos.
Otras sintaxis comunes (consulte, por ejemplo, grep -r /etc/default /etc/init*
en los sistemas Debian para las secuencias de comandos de inicio que aún no se han convertido systemd
(donde EnvironmentFile=-/etc/default/service
se utiliza para especificar un archivo de entorno opcional)) incluyen:
[ -e "$file" ] && . "$file"
Verifique que el archivo esté allí, aún consígalo si está vacío. Sigue siendo un error grave si no se puede abrir (aunque esté allí o estaba allí). Es posible que vea más variantes como [ -f "$file" ]
(existe y es un archivo normal ), [ -r "$file" ]
(es legible) o combinaciones de ellas.
[ ! -e "$file" ] || . "$file"
Una versión un poco mejor. Deja en claro que el archivo que no existe es un caso correcto. Eso también significa $?
que reflejará el estado de salida del último comando ejecutado $file
(en el caso anterior, si obtiene 1
, no sabe si es porque $file
no existió o si ese comando falló).
command . "$file"
Espere que el archivo esté allí, pero no salga si no se puede interpretar.
[ ! -e "$file" ] || command . "$file"
Combinación de lo anterior: está bien si el archivo no está allí, y para shells POSIX, las fallas para abrir (o analizar) el archivo se informan pero no son fatales (lo que puede ser más deseable ~/.profile
).
¹ Nota: zsh
Sin embargo, no se puede usar command
así a menos que en la sh
emulación; tenga en cuenta que en el shell Korn, en source
realidad es un alias para command .
, una variante no especial de.