В баше можно сделать
. /some/file || exit 1
При этом мы получим, что хотим -- или заинлайним файл /some/file, или выйдем с ошибкой:
a.sh: line 1: /some/file: No such file or directory
Просто и понятно.
А в даше (который в Debian часто стоит шелом по умолчанию) такой фокус не проходит. Самый простой вариант добиться того, что мы делаем выше -- написать
cat /some/file >/dev/null || exit 1
. /some/file || exit 1
(Второй exit 1 тут нужен для совместимости с предыдущим вариантом, если последняя команда в /some/file вернула ненулевой код). Чем плох такой вариант (кроме того, что много писанины и имя файла два раза упоминается)? А тем, что сообщение об ошибке будет менее осмысленное:
cat: /some/file: No such file or directory
Казалось бы, причём тут cat?
Вариантом, работающим в обеих шеллах, будет что-то вроде
if test -f /some/file; then
echo "/some/file: No such file or directory"
exit 1
fi
. /some/file
Вроде всё хорошо (кроме того, что кода ещё больше, имя файла упоминается уже три раза)? Ан нет! Мы проверили, что файл есть, но не проверили, можно ли его прочитать. Ну, добавим ещё один if... Но даже и это не спасёт нас, потому что системное сообщение об ошибке strerror(ENOENT) мы заменили на своё произвольное, что сводит на нет усилия локализаторов.
Итого -- лучше всего сделать через cat, а юзер пускай догадывается, причём тут cat.
Если у кого есть более кошерный вариант -- расскажите.
Page Summary
![]() ![]() ![]() ![]() ![]() ![]() ![]() |
про баш и про даш
Даже если бы это работало, то это немногим лучше варианта с if test (своё сообщение об ошибке, никакой локализации), плюс ещё один недостаток (если файл есть, но не читается, то мы получим противоречивое сообщение об ошибке). Ну, значит, так надо: > echo "File not found or unreadable" && exit 1; Ну и ещё, в порядке придирок, cat является внешней командой, может так случиться, что она не запустится (к примеру, превышен ulimit на количество процессов (-u)) — в этом случае мы получим неправильную ошибку. чего-чего по умолчанию? dash по-умолчанию только в squeeze: MYFILE="/some/file" (1) если файл есть (но у нас нет прав его читать), получим неверное сообщение об ошибке Я бы попробовал посмотреть в сторону двойного чтения файла, один из которых — в сабшелле. строго говоря, это не dash-специфика, и даже не ash-специфика. в ksh93 она тоже присутствует, например. (в отличие от bash и zsh.) к сожалению, у меня нет под рукой какой-нибудь дремучей реализации pre-posix sh, но мне очень кажется, что это изначальное поведение. Ну да. Только боюсь, заклюют. «В то время, как вся прогрессивная общественность борется с если тебе под линукс — забей, наличие /bin/bash подразумевать можно. Насколько я понимаю, классическим решением является что-то вроде: (1) в вашем варианте, если файл будет, но на нём не будет бита x, мы получим некорректное сообщение об ошибке "No such file" (вместо, скажем, "Cannot execute") Re: Я бы сделал функцию
Она не пишет сообщение об ошибке, то есть почему мы вывалились с ненулевым кодом. С другой стороны...
Почитал POSIX про операцию "dot" — там написано, что если имя файла не содержит слэш, то файл ищется в PATH. Другими словами, в общем случае все предложенные варианты, включая твой, не верны для этого случая. Re: С другой стороны...
> если имя файла не содержит слэш, то файл ищется в PATH А чем плох классический путь? if [ -r /some/file ] ; then . /some/file else exit 1 fi Если надо проверить, что файл обычный - дописать в test -a -f /some/file Спасибо, теперь мысль понятна. Поначалу не дошло, что вы хотите локализованное сообщение подручными средствами. Помимо всего прочего, у всех вариантов с проверкой заранее есть потенциальный race condition — файл может исчезнуть после проверки, но до использования :] It works for me
$ dash -c '. /some/file || exit 1'; echo $? .: 1: Can't open /some/file 2Даже "||exit 1" не обязательно, если все равно нужно прервать выполнение, а вот если прерывать не надо, то придется писать дополнительное условие, да. Re: It works for me
Это, конечно, отлично на первый взгляд. Только вот у source (он же .), в отличие от cat >/dev/null, есть всякие побочные эффекты. Мне же надо только вывалиться с ошибкой, если файла нет или он не читается. А тут ведь файл будет парситься, если там что-то не шельное — будут ошибки, если что-то шельное — оно выполнится или поменяет нам энвайромент… |