Я сделал следующий скрипт:
# !/bin/bash
# OUTPUT-COLORING
red='\e[0;31m'
green='\e[0;32m'
NC='\e[0m' # No Color
# FUNCTIONS
# directoryExists - Does the directory exist?
function directoryExists {
cd $1
if [ $? = 0 ]
then
echo -e "${green}$1${NC}"
else
echo -e "${red}$1${NC}"
fi
}
# EXE
directoryExists "~/foobar"
directoryExists "/www/html/drupal"
Сценарий работает, но помимо моего эха, есть также вывод, когда
cd $1
не удается выполнить.
testscripts//test_labo3: line 11: cd: ~/foobar: No such file or directory
Можно ли это уловить?
bash
shell
shell-script
error-handling
Томас де Уайлд
источник
источник
test -d /path/to/directory
(или[[ -d /path/to/directory ]]
в bash) скажет вам, является ли данная цель каталогом или нет, и сделает это тихо.cd
в него.directoryExists
.Ответы:
Ваш скрипт меняет каталоги во время работы, что означает, что он не будет работать с рядом относительных путей. Позже вы прокомментировали, что вам нужно только проверять наличие каталога, а не умение использовать
cd
, поэтому ответы вообще не нужно использоватьcd
. Перераб. Использованиеtput
и цвета изman terminfo
:(Отредактировано, чтобы использовать более неуязвимое
printf
вместо проблемного,echo
которое могло бы воздействовать на escape-последовательности в тексте.)источник
Используется
set -e
для установки режима выхода при ошибке: если простая команда возвращает ненулевой статус (указывает на сбой), оболочка завершается.Остерегайтесь,
set -e
это не всегда срабатывает. Команды в тестовых позициях допускаются к сбою (напримерif failing_command
,failing_command || fallback
). Команды в субоболочке только приводят к выходу подоболочки, а не родителю:set -e; (false); echo foo
дисплеиfoo
.В качестве альтернативы или в дополнение, в bash (и ksh и zsh, но не в простом sh), вы можете указать команду, которая выполняется в случае, если команда возвращает ненулевой статус, с
ERR
ловушкой, напримерtrap 'err=$?; echo >&2 "Exiting on error $err"; exit $err' ERR
. Обратите внимание, что в подобных случаях(false); …
прерывание ERR выполняется в подоболочке, поэтому оно не может привести к выходу родителя.источник
||
поведения, который позволяет легко выполнять правильную обработку ошибок без использования ловушек. Смотри мой ответ . Что вы думаете об этом методе?ERR
псевдосигнал поддерживается во всех основных оболочках. Спасибо за обзор! =)Чтобы расширить ответ @Gilles :
Действительно,
set -e
не работает внутри команд, если вы используете||
оператор после них, даже если вы запускаете их в подоболочке; например, это не сработает:Но
||
оператор необходим для предотвращения возврата из внешней функции перед очисткой.Чтобы исправить это, можно использовать небольшую хитрость: запустите внутреннюю команду в фоновом режиме, а затем сразу дождитесь ее.
wait
Встроенный возвращают код завершения внутренней команды, и теперь вы используете||
после тогоwait
, а не внутренней функции, поэтомуset -e
работает должным образом внутри последний:Вот общая функция, основанная на этой идее. Он должен работать во всех POSIX-совместимых оболочках, если вы удаляете
local
ключевые слова, т.е. заменяете всеlocal x=y
простоx=y
:Пример использования:
Выполнение примера:
Единственное, что вам необходимо знать при использовании этого метода, это то, что все изменения переменных оболочки, сделанные из команды, которую вы передаете
run
, не будут распространяться на вызывающую функцию, потому что команда выполняется в подоболочке.источник
Вы не говорите, что именно вы подразумеваете под
catch
--- сообщайте и продолжайте; прервать дальнейшую обработку?Поскольку
cd
при сбое возвращает ненулевое состояние, вы можете сделать:Вы можете просто выйти при неудаче:
Или введите свое собственное сообщение и выйдите:
И / или подавить ошибку, возникшую при
cd
сбое:По стандартам команды должны помещать сообщения об ошибках в STDERR (дескриптор файла 2). Таким образом,
2>/dev/null
говорится, перенаправить STDERR к «битовой корзине», известной/dev/null
.(не забудьте процитировать ваши переменные и отметить конец параметров для
cd
).источник
На самом деле для вашего случая я бы сказал, что логика может быть улучшена.
Вместо cd и затем проверьте, существует ли он, проверьте, существует ли он, затем перейдите в каталог.
Но если ваша цель состоит в том, чтобы заставить замолчать возможные ошибки, то
cd -- "$1" 2>/dev/null
это сделает вашу отладку в будущем более сложной. Вы можете проверить флаги тестирования if на: Bash, если документация :источник
$1
переменную и потерпит неудачу, если эта переменная содержит пробелы или другие метасимволы оболочки. Он также не может проверить, есть ли у пользователя разрешениеcd
на это.