В оболочках POSIX .
это специальная встроенная функция, поэтому ее сбой приводит к выходу оболочки (в некоторых оболочках, например bash
, это происходит только в режиме POSIX).
То, что считается ошибкой, зависит от оболочки. Не все из них выходят из-за синтаксической ошибки при разборе файла, но большинство из них завершается, когда исходный файл не может быть найден или открыт. Я не знаю ничего, что могло бы завершиться, если последняя команда в исходном файле вернулась с ненулевым статусом выхода (если, errexit
конечно, опция не включена).
Здесь делают:
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
Это тот случай, когда вы хотите получить исходный файл, если он там, и нет, если его нет (или здесь пусто -s
).
То есть, это не должно считаться ошибкой (фатальная ошибка в оболочках POSIX), если файла нет, этот файл считается необязательным файлом.
Это все равно будет (фатальной) ошибкой, если файл не будет читаемым, или каталогом, или (в некоторых оболочках) при синтаксической ошибке при синтаксическом анализе, которая будет представлять собой реальные ошибки, о которых следует сообщать.
Некоторые утверждают, что есть состояние гонки. Но единственное, что это означает, это то, что оболочка завершит работу с ошибкой, если файл будет удален между [
и .
, но я бы сказал, что допустимо считать ошибкой, что этот файл с фиксированным путем внезапно исчезнет, пока скрипт Бег.
С другой стороны,
command . "$NVM_DIR/nvm.sh" 2> /dev/null
где command
¹ удаляет специальный атрибут .
команды (поэтому он не выходит из оболочки при ошибке) не будет работать так:
- это скрыло бы
.
ошибки, но также и ошибки команд, выполняемых в исходном файле
- это также скрыло бы реальные ошибки, такие как файл с неправильными разрешениями.
Другие распространенные синтаксисы (см., Например, grep -r /etc/default /etc/init*
в системах Debian сценарии инициализации, в которые еще не были преобразованы systemd
(где EnvironmentFile=-/etc/default/service
вместо этого используется дополнительный файл среды)):
[ -e "$file" ] && . "$file"
Проверьте файл, который там есть, все равно отправьте его, если он пуст. Все еще фатальная ошибка, если она не может быть открыта (даже если она там или была там). Вы можете увидеть больше вариантов, таких как [ -f "$file" ]
(существует и является обычным файлом), [ -r "$file" ]
(доступно для чтения) или их комбинаций.
[ ! -e "$file" ] || . "$file"
Немного лучшая версия. Проясняет, что несуществующий файл является нормальным случаем. Это также означает, что $?
будет отображать состояние выхода последней команды, запущенной в $file
(в предыдущем случае, если вы получаете 1
, вы не знаете, потому что $file
это не было или эта команда не выполнена).
command . "$file"
Ожидайте, что файл будет там, но не выходите, если он не может быть интерпретирован.
[ ! -e "$file" ] || command . "$file"
Комбинация вышесказанного: все нормально, если файла нет, а для оболочек POSIX сообщается об ошибках открытия (или разбора) файла, но они не являются фатальными (что может быть более желательным для ~/.profile
).
¹ Примечание: zsh
однако, вы не можете использовать command
это, если не в sh
эмуляции; обратите внимание, что в оболочке Korn, source
на самом деле псевдоним для command .
, не особый вариант.