Bash, or the Bourne-Again Shell, is a powerful command-line interface (CLI) that is commonly used in Linux and Unix systems. When working with Bash, it is important to understand how to handle errors that may occur during the execution of commands. In this article, we will discuss various ways to understand and ignore errors in Bash. Bash scripting is a powerful tool for automating and simplifying various tasks in Linux and Unix systems. However, errors can occur during the execution of commands and can cause scripts to fail. In this article, we will explore the various ways to understand and handle errors in Bash. We will look at ways to check the exit status code and error messages of commands, as well as techniques for ignoring errors when necessary. By understanding and properly handling errors, you can ensure that your Bash scripts run smoothly and achieve the desired outcome.
Step-by-step approach for understanding and ignoring errors in Bash:
Step 1: Understand how errors are generated in Bash.
- When a command is executed, it returns an exit status code.
- A successful command will have an exit status of 0, while a failed command will have a non-zero exit status.
- Error messages are generated when a command returns a non-zero exit status code.
Step 2: Check the exit status code of a command.
- To check the exit status code of a command, you can use the $? variable, which holds the exit status of the last executed command.
- For example, after executing the command ls non_existent_directory, you can check the exit status code by running echo $? The output
- will be non-zero (e.g., 2) indicating that the command failed.
Step 3: Check the error message of a command.
- To check the error message of a command, you can redirect the standard error output (stderr) to a file or to the standard output (stdout) using the 2> operator.
- For example, you can redirect the stderr of the command ls non_existent_directory to a file by running ls non_existent_directory 2> error.log. Then you can view the error message by running cat error.log.
Step 4: Use the set -e command.
- The set -e command causes the script to exit immediately if any command exits with a non-zero status. This can be useful for detecting and handling errors early on in a script.
- For example, if you run set -e followed by ls non_existent_directory, the script will exit immediately with an error message.
Step 5: Ignore errors when necessary.
- To ignore errors, you can use the command || true construct. This construct allows you to execute a command, and if it returns a non-zero exit status, the command following the || operator (in this case, true) will be executed instead.
- For example, you can run rm non_existent_file || true to remove a file that does not exist without exiting with an error.
- Another way to ignore errors is to use the command 2> /dev/null construct, which redirects the standard error output (stderr) of a command to the null device, effectively ignoring any error messages.
- Additionally, you can use the command 2>&1 >/dev/null construct to ignore both standard error and standard output.
- You can also use the command || : construct which allows you to execute a command and if it returns a non-zero exit status, the command following the || operator (in this case, 🙂 will be executed instead. The: command is a no-op command that does nothing, effectively ignoring the error.
Practical Explanation for Understanding Errors
First, let’s examine how errors are generated in Bash. When a command is executed, it returns an exit status code. This code indicates whether the command was successful (exit status 0) or not (non-zero exit status). For example, the following command attempts to list the files in a directory that does not exist:
$ ls non_existent_directory ls: cannot access 'non_existent_directory': No such file or directory
As you can see, the command generated an error message and returned a non-zero exit status code. To check the exit status code of a command, you can use the $? variable, which holds the exit status of the last executed command.
$ echo $? 2
In addition to the exit status code, you can also check the standard error output (stderr) of a command to understand errors. This can be done by redirecting the stderr to a file or to the standard output (stdout) using the 2> operator.
For example, the following script will redirect the stderr of a command to a file:
$ ls non_existent_directory 2> error.log $ cat error.log ls: cannot access 'non_existent_directory': No such file or directory
You can also redirect the stderr to the stdout using the 2>&1 operator, which allows you to see the error message along with the standard output of the command.
$ ls non_existent_directory 2>&1 ls: cannot access 'non_existent_directory': No such file or directory
Another useful tool for understanding errors is the set -e command, which causes the script to exit immediately if any command exits with a non-zero status. This can be useful for detecting and handling errors early on in a script.
$ set -e $ ls non_existent_directory # as soon as you hit enter this will exit shell and will close the terminal.
After this command script will exit from the shell if the exit code is nonzero.
Practical Explanation for Ignoring Errors
While it is important to handle errors in Bash scripts, there may be certain situations where you want to ignore errors and continue running the script. In this section, we will discuss different methods for ignoring errors in Bash and provide examples of how to implement them.
Heredoc
Heredoc is a feature in Bash that allows you to specify a string or command without having to escape special characters. This can be useful when you want to ignore errors that may occur while executing a command. The following example demonstrates how to use Heredoc to ignore errors.
#!/bin/bash # Example of ignoring errors using Heredoc # The `command` will fail but it will not stop execution cat <<EOF | while read line; do echo $line done command that will fail EOF # Rest of the script
In this example, the command that is inside the Heredoc will fail, but the script will not stop execution. This is because the output of the command is piped to the while loop, which reads the output and ignores the error.
Pipefail
The pipe fails option in Bash can be used to change the behavior of pipelines so that the exit status of the pipeline is the value of the last (rightmost) command to exit with a non-zero status or zero if all commands exit successfully. This can be useful when you want to ignore errors that may occur while executing multiple commands in a pipeline. The following example demonstrates how to use the pipe fail option to ignore errors.
#!/bin/bash # Example of ignoring errors using pipefail # The `command1` will fail but it will not stop execution set -o pipefail command1 | command2 # Rest of the script
In this example, command1 will fail, but command2 will continue to execute, and the script will not stop execution.
Undefined Variables
By default, Bash will stop the execution of a script if an undefined variable is used. However, you can use the -u option to ignore this behavior and continue running the script even if an undefined variable is used. The following example demonstrates how to ignore undefined variables.
#!/bin/bash # Example of ignoring undefined variables set +u echo $undefined_variable # Rest of the script
In this example, the script will not stop execution when an undefined variable is used.
Compiling and Interpreting
When compiling or interpreting a script, errors may occur. However, these errors can be ignored by using the -f option when running the script. The following example demonstrates how to ignore errors when compiling or interpreting a script.
#!/bin/bash # Example of ignoring errors when compiling or interpreting bash -f script.sh # Rest of the script
In this example, the script will continue to run even if there are errors during the compilation or interpretation process.
Traps
A trap is a way to execute a command or a set of commands when a specific signal is received by the script. This can be useful when you want to ignore errors and run a cleanup command instead. The following example demonstrates how to use a trap to ignore errors.
#!/bin/bash # Example of ignoring errors using a trap # Set a trap to run the cleanup function when an error occurs trap cleanup ERR # Function to run when an error occurs cleanup() { echo "Cleaning up before exiting..." } # Command that will cause an error command_that_will_fail # Rest of the script
In this example, when the command_that_will_fail causes an error, the script will execute the cleanup function instead of stopping execution. This allows you to perform any necessary cleanup before exiting the script.
Examples of Bash for Error Handling:
Example 1: Error Handling Using a Conditional Condition
One way to handle errors in Bash is to use a conditional statement. The following example demonstrates how to check for a specific error and handle it accordingly.
#!/bin/bash # Example of error handling using a conditional condition file=example.txt if [ ! -f $file ]; then echo "Error: $file does not exist" exit 1 fi # Rest of the script
In this example, we check if the file “example.txt” exists using the -f option of the [ command. If the file does not exist, the script will print an error message and exit with a status code of 1. This allows the script to continue running if the file exists and exit if it does not.
Example 2: Error Handling Using the Exit Status Code
Another way to handle errors in Bash is to check the exit status code of a command. Every command in Bash returns an exit status code when it completes, with a code of 0 indicating success and any other code indicating an error. The following example demonstrates how to check the exit status code of a command and handle it accordingly.
#!/bin/bash # Example of error handling using the exit status code command1 if [ $? -ne 0 ]; then echo "Error: command1 failed" exit 1 fi # Rest of the script
In this example, the script runs the command “command1” and then checks the exit status code using the special variable $?. If the exit status code is not 0, the script will print an error message and exit with a status code of 1.
Example 3: Stop the Execution on the First Error
When running a script, it can be useful to stop the execution on the first error that occurs. This can be achieved by using the set -e command, which tells Bash to exit the script if any command exits with a non-zero status code.
#!/bin/bash # Stop execution on the first error set -e command1 command2 command3 # Rest of the script
In this example, if any of the commands “command1”, “command2” or “command3” fail, the script will exit immediately.
Example 4: Stop the Execution for Uninitialized Variable
Another way to stop execution on error is if an uninitialized variable is used during script execution. This can be achieved by using the set -u command, which tells Bash to exit the script if any uninitialized variable is used.
#!/bin/bash # Stop execution for uninitialized variable set -u echo $uninitialized_variable # Rest of the script
In this example, if the uninitialized_variable is not defined, the script will exit immediately.
Conclusion
In conclusion, understanding and ignoring errors in Bash is an important aspect of working with the command-line interface. By checking the exit status code of a command, its associated error message, and redirecting the stderr to a file or the stdout, you can understand what went wrong. And by using the command || true, command 2> /dev/null, command 2>&1 >/dev/null, and command || : constructs, you can ignore errors when necessary. It’s always a good practice to test these constructs in a testing environment before using them in production.
я извиняюсь, не уточнил обстоятельства)
Есть exe приложение , в нем есть к примеру класс с виртуальными функциями внутри
C++ (Qt) | ||
|
Я делаю перехват поинтера этого класса(обычный хук) и получаю доступ к его объектам класса и вообще всей памяти приложения в целом, НО я не знаю в каком порядке расположены виртуальные функции внутри класса. Так как я не знаю асму , то не смогу посмотреть в дизассемблере какого типа функция и восстановить её, делать прототип класса и переставлять каждую функцию местами чтобы не ошибиться и вызвать её правильно — не дело! так вот как мне быть , если я например сделаю вызов
а на её месте на самом деле будет функция
C++ | ||
|
естественно вызов будет не верный и приложение закроется с ошибкой, как мне при неправильном вызове функции , как бы «проигнорировать» собственно её не правильный вызов, обработать ошибку и продолжить работу программы, пробовал :
C++ | ||
|
не помогло
Я использую следующие варианты
set -o pipefail
set -e
В скрипте bash остановить выполнение при ошибке. У меня ~ 100 строк выполнения скрипта, и я не хочу проверять код возврата каждой строки в скрипте.
Но для одной конкретной команды я хочу игнорировать ошибку. Как я могу это сделать?
Ответ 1
Решение:
particular_script || true
Пример:
$ cat /tmp/1.sh
particular_script()
{
false
}
set -e
echo ein
particular_script || true
echo zwei
particular_script
echo drei
$ bash /tmp/1.sh
ein
zwei
drei
никогда не будет напечатан.
Кроме того, я хочу добавить, что, когда pipefail
включен,
достаточно, чтобы оболочка подумала, что весь канал имеет ненулевой код выхода
когда одна из команд в трубе имеет ненулевой код выхода (при этом pipefail
он должен быть последним).
$ set -o pipefail
$ false | true ; echo $?
1
$ set +o pipefail
$ false | true ; echo $?
0
Ответ 2
Просто добавьте || true
после команды, в которой вы хотите проигнорировать ошибку.
Ответ 3
Более кратко:
! particular_script
Из спецификации POSIX относительно set -e
(выделено мной):
Если этот параметр включен, если простая команда не выполняется по любой из причин, перечисленных в Последствиях ошибок оболочки, или возвращает значение состояния выходa > 0 и не является частью составного списка через некоторое время, пока, или если ключевое слово и не является частью списка AND или OR и не является конвейером , которому предшествует! зарезервированное слово, то оболочка должна немедленно выйти.
Ответ 4
Не останавливайтесь и сохраняйте статус выхода
На всякий случай, если вы хотите, чтобы ваш сценарий не останавливался, если какая-то команда не выполнена, и вы также хотите сохранить код ошибки неудачной команды:
set -e
EXIT_CODE=0
command || EXIT_CODE=$?
echo $EXIT_CODE
Ответ 5
Вместо «возврата true» вы также можете использовать утилиту «noop» или null (как указано в спецификации POSIX) :
и просто «ничего не делать». Вы сохраните несколько писем.
#!/usr/bin/env bash
set -e
man nonexistentghing || :
echo "It ok.."
Ответ 6
Я использовал приведенный ниже фрагмент при работе с инструментами CLI и хочу знать, существует какой-то ресурс или нет, но меня не волнует вывод.
if [ -z "$(cat no_exist 2>&1 >/dev/null)" ]; then
echo "none exist actually exist!"
fi
Ответ 7
в то время как || true
|| true
является предпочтительным, но вы также можете сделать
var=$(echo $(exit 1)) # it shouldn't fail
Ответ 8
Мне нравится это решение:
: 'particular_script'
Команда/скрипт между обратными галочками выполняется, и ее вывод подается на команду «:» (что эквивалентно «true»)
$ false
$ echo $?
1
$ : 'false'
$ echo $?
0
редактировать: исправлена некрасивая опечатка
Ответ 9
Если вы хотите предотвратить сбой сценария и собрать код возврата:
command () {
return 1 # or 0 for success
}
set -e
command && returncode=$? || returncode=$?
echo $returncode
returncode
собирается независимо от того, выполнена команда или нет.
Я использую следующие варианты
set -o pipefail
set -e
В скрипте bash остановить выполнение при ошибке. У меня ~ 100 строк выполнения скрипта, и я не хочу проверять код возврата каждой строки в скрипте.
Но для одной конкретной команды я хочу игнорировать ошибку. Как я могу это сделать?
Ответ 1
Решение:
particular_script || true
Пример:
$ cat /tmp/1.sh
particular_script()
{
false
}
set -e
echo ein
particular_script || true
echo zwei
particular_script
echo drei
$ bash /tmp/1.sh
ein
zwei
drei
никогда не будет напечатан.
Кроме того, я хочу добавить, что, когда pipefail
включен,
достаточно, чтобы оболочка подумала, что весь канал имеет ненулевой код выхода
когда одна из команд в трубе имеет ненулевой код выхода (при этом pipefail
он должен быть последним).
$ set -o pipefail
$ false | true ; echo $?
1
$ set +o pipefail
$ false | true ; echo $?
0
Ответ 2
Просто добавьте || true
после команды, в которой вы хотите проигнорировать ошибку.
Ответ 3
Более кратко:
! particular_script
Из спецификации POSIX относительно set -e
(выделено мной):
Если этот параметр включен, если простая команда не выполняется по любой из причин, перечисленных в Последствиях ошибок оболочки, или возвращает значение состояния выходa > 0 и не является частью составного списка через некоторое время, пока, или если ключевое слово и не является частью списка AND или OR и не является конвейером , которому предшествует! зарезервированное слово, то оболочка должна немедленно выйти.
Ответ 4
Не останавливайтесь и сохраняйте статус выхода
На всякий случай, если вы хотите, чтобы ваш сценарий не останавливался, если какая-то команда не выполнена, и вы также хотите сохранить код ошибки неудачной команды:
set -e
EXIT_CODE=0
command || EXIT_CODE=$?
echo $EXIT_CODE
Ответ 5
Вместо «возврата true» вы также можете использовать утилиту «noop» или null (как указано в спецификации POSIX) :
и просто «ничего не делать». Вы сохраните несколько писем.
#!/usr/bin/env bash
set -e
man nonexistentghing || :
echo "It ok.."
Ответ 6
Я использовал приведенный ниже фрагмент при работе с инструментами CLI и хочу знать, существует какой-то ресурс или нет, но меня не волнует вывод.
if [ -z "$(cat no_exist 2>&1 >/dev/null)" ]; then
echo "none exist actually exist!"
fi
Ответ 7
в то время как || true
|| true
является предпочтительным, но вы также можете сделать
var=$(echo $(exit 1)) # it shouldn't fail
Ответ 8
Мне нравится это решение:
: 'particular_script'
Команда/скрипт между обратными галочками выполняется, и ее вывод подается на команду «:» (что эквивалентно «true»)
$ false
$ echo $?
1
$ : 'false'
$ echo $?
0
редактировать: исправлена некрасивая опечатка
Ответ 9
Если вы хотите предотвратить сбой сценария и собрать код возврата:
command () {
return 1 # or 0 for success
}
set -e
command && returncode=$? || returncode=$?
echo $returncode
returncode
собирается независимо от того, выполнена команда или нет.
Bas: Модуль Логика Скрипта — Функция Игнорирование Ошибок Скрипта В Bas, Как Применять
Automation Empire — Павел Дуглас On Bas
HD
08:44
Bas: Модуль Логика Скрипта — Функция Игнорирование Ошибок Скрипта В Bas, Как Применять
Automation Empire — Павел Дуглас On Bas
.
219 Видео
Дата публикации:
25.02.2021 18:45
Продолжительность:
08:44
Ссылка:
https://thewikihow.com/video_86Be1srqTxI
Действия:
Жалоба
Связаться с автором
Источник:
Описание
BAS — Модуль Браузер — Функция ИГНОРИРОВАНИЕ ОШИБОК скрипта в BAS, как применять
Добавляйтесь в друзья:
👱 Я в Децентрализованных Blockchain сетях:
Павел Дуглас канал Бот Мейкер — Всё про создание ботов для автоматизации любых рутинных действий в бизнесе, заработке или для личных нужд. Узнайте все фишки ботоводов и ботмейкеров на этом канале. Канал ведет эксперт по заработку в интернете, онлайн бизнесу, криптовалютам и автоматизации.
#Павел_Дуглас #Browser_Automation_Studio #BAS
Возможно вы искали — визуальное программирование
примеры программ по bas
bas уроки
примеры bas
заказать скрипт бас
bablosoft
bas интересные уроки
bas новые уроки
создание на bas бота под кран
browser automation script logic
bas с разными задачами
browser automation studio tutorial
пример скрипта bas
уроки по browserautomationstudio
browserautomationstudio что это
автоматизируем процесс в bas
изучаем browserautomationstudio
бот для заработка
как заработать в интернете
заработать школьнику
боты для заработка реальных денег
зарабатываем легко
бот для заработка денег
бот для сбора биткоинов
создать бот для бизнеса
создать бота онлайн
создать бота без программирования
Новые видео на канале Automation Empire — Павел Дуглас On Bas
- Автоматический Парсер Доменов Для Нагула Куков С Facebook Pixel Бесплатно И Без Ограничений
- [Кейсы Browser Automation Studio] — Wildberries Регер И Рассыльщик По Селлерам + Продвигатель Бренда
- [Кейсы Browser Automation Studio] — Yappy Bot Накрути Себе 1 000 000 Просмотров, Лайков, Комментов
Подписывайтесь на наш Telegram канал!@thewikihowоткрытьМониторим видео тренды 24/7
Что еще посмотреть на канале Automation Empire — Павел Дуглас On Bas
Фото обложки и кадры из видео
Bas: Модуль Логика Скрипта — Функция Игнорирование Ошибок Скрипта В Bas, Как Применять, Automation Empire — Павел Дуглас On Bas
https://thewikihow.com/video_86Be1srqTxI
Аналитика просмотров видео на канале Automation Empire — Павел Дуглас On Bas
Гистограмма просмотров видео «Bas: Модуль Логика Скрипта — Функция Игнорирование Ошибок Скрипта В Bas, Как Применять» в сравнении с последними загруженными видео.
Теги:
Browser Automation Studio
Павел Дуглас
Browser Automation Studio Игнорирование Ошибок В Скрипте
Browser Automation Studio Скачать Торрент
Browser Automation Studio Скрипты
Browser Automation Studio Уроки
Browser Automation Studio Скачать
Browser Automation Studio Мануал
Browser Automation Studio На Русском
Browser Automation Studio Обучение
Browser Automation Studio Официальный Сайт На Русском
Browser Automation Studio Премиум Скачать
Похожие видео
15:02
Как Работать С Расширениями В Bas, Bas Extensions И Работа С Ними На Примере Touch Vpn
3 371 просмотр.
10:50
Bas: Модуль Логика Скрипта — Функции Установить Метку И Перейти К Метке Скрипта В Bas
546 просмотров.
04:32
Bas: Модуль Логика Скрипта — Цикл For (I = 0 To N), Цикл For В Browser Automation Studio
713 просмотров.
14:36
Как Использовать Ресурсы Внутри Browser Automation Studio, Bas Урок По Ресурсам
1 919 просмотров.
15:08
Как Парсить Каждый Раз Новую Строку С Прокси И Применять Ее При Работе С Bas, Foreach + Парсинг
6 465 просмотров.
10:50
Bas: Модуль Логика Скрипта — Условие If, Как Работает Func-Условие If В Browser Automation Studio
2 924 просмотра.
21:03
Как Работать С Куками В Bas, Загружаем Cookies В Browser Automation Studio
3 297 просмотров.
11:26
Создание Сводной Таблицы В Excel
1 966 844 просмотра.
08:10
Проблема Числа 10958 [Numberphile]
6 257 189 просмотров.
Все мы знаем, что BAS не идеальна и в ней есть ошибки, которые в последующих версиях программы исправляются. А благодаря подписке на «ІТС», Вы всегда будете в курсе уже существующих ошибок, и Вам будет предоставлена ссылка на перечень всех ошибок: в этом перечне Вы найдете список проблем, с которыми уже столкнулись пользователи и ответ разработчиков, в каких версиях программы планируется исправление ошибок.
Также, имея подписку на «ІТС» Вы сможете зарегистрировать найденную Вами ошибку, и разработчики сообщат, в каком релизе она будет исправлена. Ошибки конфигураций Вы можете посмотреть по ссылке.
На сегодня, компании, которые сопровождают и обслуживают BAS, спрашивают о наличии договора «ІТС».
«ІТС» – это поддержка, сопровождение и необходимый спектр услуг для любого пользователя:
- лицензионные обновления,
- консультации,
- комментарии,
- FREDO Звіт и многое другое.
- лицензионное обновление BAS;
- доступ к существующим ошибкам конфигураций и сроки их исправления;
- доступ к ИС и к Порталу «ІТС»;
- линия консультаций от сопровождающей компании.
- «ІТС» Проф;
- «ІТС» Техно.
С основными отличиями «ІТС» Проф и «ІТС» Техно и стоимостью подписки на «ІТС», Вы можете ознакомиться, перейдя по ссылке.
То есть, приобретая договор «ІТС», Вы получаете доступ к порталу и сервисам «ІТС», где собраны все рекомендации по работе с программой BAS, также необходимая помощь финансистам, бухгалтерам и экономистам: сервисы «ІТС» помогут найти всю необходимую Вам информацию, касающуюся законодательства или правильности ведения учёта в Вашей базе, что соответственно сэкономит Ваши средства. В случае, если Вы не найдёте ответ, на интересующий Вас вопрос, Вы всегда сможете задать его аудитору на портале «ІТС».
Также, после покупки «ІТС» Проф у компании FinSoft, Вам предоставляется несколько бесплатных часов в год, которые Вы можете потратить как на консультации по программе BAS (типовой), так и на установку обновлений.
Обзаведясь подпиской на «ІТС», Вы можете, не прибегая к помощи специалистов BAS, самостоятельно решать некоторые проблемы, поскольку многие ситуации уже рассмотрены и описаны на портале «ІТС»; а также портал «ІТС» очень полезен для каждого сотрудника на Вашей фирме – будь то бухгалтер или технический специалист.
Приобретайте подписку на «ІТС», и Вы ощутите все преимущества данного сервиса!
И помните, установка обновлений без действующей подписки «ІТС» — приравнивается к использованию пиратского программного обеспечения и влечет за собой ответственность в рамках действующего законодательства.
Также, наша компания проводит обучение по курсам:
- Авторские курсы BAS
- Онлайн курсы BAS
Обучение проводится в вечернее время, что позволит вам не отрываться от работы или обучения, практикующим программистом нашей компании.
Если у вас остались вопросы, Вы всегда можете обратиться к нашим аналитикам по телефонам:
(093) 090-70-20
(095) 090-70-20
(068) 090-70-20
Написание надежного, без ошибок сценария bash всегда является сложной задачей. Даже если вы написать идеальный сценарий bash, он все равно может не сработать из-за внешних факторов, таких как некорректный ввод или проблемы с сетью.
В оболочке bash нет никакого механизма поглощения исключений, такого как конструкции try/catch. Некоторые ошибки bash могут быть молча проигнорированы, но могут иметь последствия в дальнейшем.
Проверка статуса завершения команды
Всегда рекомендуется проверять статус завершения команды, так как ненулевой статус выхода обычно указывает на ошибку
if ! command; then
echo "command returned an error"
fi
Другой (более компактный) способ инициировать обработку ошибок на основе статуса выхода — использовать OR:
<command_1> || <command_2>
С помощью оператора OR, <command_2> выполняется тогда и только тогда, когда <command_1> возвращает ненулевой статус выхода.
В качестве второй команды, можно использовать свою Bash функцию обработки ошибок
error_exit()
{
echo "Error: $1"
exit 1
}
bad-command || error_exit "Some error"
В Bash имеется встроенная переменная $?, которая сообщает вам статус выхода последней выполненной команды.
Когда вызывается функция bash, $? считывает статус выхода последней команды, вызванной внутри функции. Поскольку некоторые ненулевые коды выхода имеют специальные значения, вы можете обрабатывать их выборочно.
status=$?
case "$status" in
"1") echo "General error";;
"2") echo "Misuse of shell builtins";;
"126") echo "Command invoked cannot execute";;
"128") echo "Invalid argument";;
esac
Выход из сценария при ошибке в Bash
Когда возникает ошибка в сценарии bash, по умолчанию он выводит сообщение об ошибке в stderr, но продолжает выполнение в остальной части сценария. Даже если ввести неправильную команду, это не приведет к завершению работы сценария. Вы просто увидите ошибку «command not found».
Такое поведение оболочки по умолчанию может быть нежелательным для некоторых bash сценариев. Например, если скрипт содержит критический блок кода, в котором не допускаются ошибки, вы хотите, чтобы ваш скрипт немедленно завершал работу при возникновении любой ошибки внутри этого блока . Чтобы активировать это поведение «выход при ошибке» в bash, вы можете использовать команду set следующим образом.
set -e
# некоторый критический блок кода, где ошибка недопустима
set +e
Вызванная с опцией -e, команда set заставляет оболочку bash немедленно завершить работу, если любая последующая команда завершается с ненулевым статусом (вызванным состоянием ошибки). Опция +e возвращает оболочку в режим по умолчанию. set -e эквивалентна set -o errexit. Аналогично, set +e является сокращением команды set +o errexit.
set -e
true | false | true
echo "Это будет напечатано" # "false" внутри конвейера не обнаружено
Если необходимо, чтобы при любом сбое в работе конвейеров также завершался сценарий bash, необходимо добавить опцию -o pipefail.
set -o pipefail -e
true | false | true # "false" внутри конвейера определен правильно
echo "Это не будет напечатано"
Для «защиты» критический блока в сценарии от любого типов ошибок команд или ошибок конвейера, необходимо использовать следующую комбинацию команд set.
set -o pipefail -e
# некоторый критический блок кода, в котором не допускается ошибка или ошибка конвейера
set +o pipefail +e
В Powershell существует несколько уровней ошибок и несколько способов их обработать. Проблемы одного уровня (Non-Terminating Errors) можно решить с помощью привычных для Powershell команд. Другой уровень ошибок (Terminating Errors) решается с помощью исключений (Exceptions) стандартного, для большинства языков, блока в виде Try, Catch и Finally.
Как Powershell обрабатывает ошибки
До рассмотрения основных методов посмотрим на теоретическую часть.
Автоматические переменные $Error
В Powershell существует множество переменных, которые создаются автоматически. Одна из таких переменных — $Error хранит в себе все ошибки за текущий сеанс PS. Например так я выведу количество ошибок и их сообщение за весь сеанс:
Get-TestTest
$Error
$Error.Count
При отсутствии каких либо ошибок мы бы получили пустой ответ, а счетчик будет равняться 0:
Переменная $Error являет массивом и мы можем по нему пройтись или обратиться по индексу что бы найти нужную ошибку:
$Error[0]
foreach ($item in $Error){$item}
Свойства объекта $Error
Так же как и все что создается в Powershell переменная $Error так же имеет свойства (дополнительную информацию) и методы. Названия свойств и методов можно увидеть через команду Get-Member:
$Error | Get-Member
Например, с помощью свойства InvocationInfo, мы можем вывести более структурный отчет об ошибки:
$Error[0].InvocationInfo
Методы объекта $Error
Например мы можем очистить логи ошибок используя clear:
$Error.clear()
Критические ошибки (Terminating Errors)
Критические (завершающие) ошибки останавливают работу скрипта. Например это может быть ошибка в названии командлета или параметра. В следующем примере команда должна была бы вернуть процессы «svchost» дважды, но из-за использования несуществующего параметра ‘—Error’ не выполнится вообще:
'svchost','svchost' | % {Get-Process -Name $PSItem} --Error
Не критические ошибки (Non-Terminating Errors)
Не критические (не завершающие) ошибки не остановят работу скрипта полностью, но могут вывести сообщение об этом. Это могут быть ошибки не в самих командлетах Powershell, а в значениях, которые вы используете. На предыдущем примере мы можем допустить опечатку в названии процессов, но команда все равно продолжит работу:
'svchost111','svchost' | % {Get-Process -Name $PSItem}
Как видно у нас появилась информация о проблеме с первым процессом ‘svchost111’, так как его не существует. Обычный процесс ‘svchost’ он у нас вывелся корректно.
Параметр ErrorVariable
Если вы не хотите использовать автоматическую переменную $Error, то сможете определять свою переменную индивидуально для каждой команды. Эта переменная определяется в параметре ErrorVariable:
'svchost111','svchost' | % {Get-Process -Name $PSItem } -ErrorVariable my_err_var
$my_err_var
Переменная будет иметь те же свойства, что и автоматическая:
$my_err_var.InvocationInfo
Обработка некритических ошибок
У нас есть два способа определения последующих действий при ‘Non-Terminating Errors’. Это правило можно задать локально и глобально (в рамках сессии). Мы сможем полностью остановить работу скрипта или вообще отменить вывод ошибок.
Приоритет ошибок с $ErrorActionPreference
Еще одна встроенная переменная в Powershell $ErrorActionPreference глобально определяет что должно случится, если у нас появится обычная ошибка. По умолчанию это значение равно ‘Continue’, что значит «вывести информацию об ошибке и продолжить работу»:
$ErrorActionPreference
Если мы поменяем значение этой переменной на ‘Stop’, то поведение скриптов и команд будет аналогично критичным ошибкам. Вы можете убедиться в этом на прошлом скрипте с неверным именем процесса:
$ErrorActionPreference = 'Stop'
'svchost111','svchost' | % {Get-Process -Name $PSItem}
Т.е. скрипт был остановлен в самом начале. Значение переменной будет храниться до момента завершения сессии Powershell. При перезагрузке компьютера, например, вернется значение по умолчанию.
Ниже значение, которые мы можем установить в переменной $ErrorActionPreference:
- Continue — вывод ошибки и продолжение работы;
- Inquire — приостановит работу скрипта и спросит о дальнейших действиях;
- SilentlyContinue — скрипт продолжит свою работу без вывода ошибок;
- Stop — остановка скрипта при первой ошибке.
Самый частый параметр, который мне приходится использовать — SilentlyContinue:
$ErrorActionPreference = 'SilentlyContinue'
'svchost111','svchost' | % {Get-Process -Name $PSItem}
Использование параметра ErrorAction
Переменная $ErrorActionPreference указывает глобальный приоритет, но мы можем определить такую логику в рамках команды с параметром ErrorAction. Этот параметр имеет больший приоритет чем $ErrorActionPreference. В следующем примере, глобальная переменная определяет полную остановку скрипта, а в параметр ErrorAction говорит «не выводить ошибок и продолжить работу»:
$ErrorActionPreference = 'Stop'
'svchost111','svchost' | % {Get-Process -Name $PSItem -ErrorAction 'SilentlyContinue'}
Кроме ‘SilentlyContinue’ мы можем указывать те же параметры, что и в переменной $ErrorActionPreference.
Значение Stop, в обоих случаях, делает ошибку критической.
Обработка критических ошибок и исключений с Try, Catch и Finally
Когда мы ожидаем получить какую-то ошибку и добавить логику нужно использовать Try и Catch. Например, если в вариантах выше мы определяли нужно ли нам отображать ошибку или останавливать скрипт, то теперь сможем изменить выполнение скрипта или команды вообще. Блок Try и Catch работает только с критическими ошибками и в случаях если $ErrorActionPreference или ErrorAction имеют значение Stop.
Например, если с помощью Powershell мы пытаемся подключиться к множеству компьютеров один из них может быть выключен — это приведет к ошибке. Так как эту ситуацию мы можем предвидеть, то мы можем обработать ее. Процесс обработки ошибок называется исключением (Exception).
Синтаксис и логика работы команды следующая:
try {
# Пытаемся подключиться к компьютеру
}
catch [Имя исключения 1],[Имя исключения 2]{
# Раз компьютер не доступен, сделать то-то
}
finally {
# Блок, который выполняется в любом случае последним
}
Блок try мониторит ошибки и если она произойдет, то она добавится в переменную $Error и скрипт перейдет к блоку Catch. Так как ошибки могут быть разные (нет доступа, нет сети, блокирует правило фаервола и т.д.) то мы можем прописывать один блок Try и несколько Catch:
try {
# Пытаемся подключится
}
catch ['Нет сети']['Блокирует фаервол']{
# Записываем в файл
}
catch ['Нет прав на подключение']{
# Подключаемся под другим пользователем
}
Сам блок finally — не обязательный и используется редко. Он выполняется самым последним, после try и catch и не имеет каких-то условий.
Catch для всех типов исключений
Как и было показано выше мы можем использовать блок Catch для конкретного типа ошибок, например при проблемах с доступом. Если в этом месте ничего не указывать — в этом блоке будут обрабатываться все варианты ошибок:
try {
'svchost111','svchost' | % {Get-Process -Name $PSItem -ErrorAction 'Stop'}
}
catch {
Write-Host "Какая-то неисправность" -ForegroundColor RED
}
Такой подход не рекомендуется использовать часто, так как вы можете пропустить что-то важное.
Мы можем вывести в блоке catch текст ошибки используя $PSItem.Exception:
try {
'svchost111','svchost' | % {Get-Process -Name $PSItem -ErrorAction 'Stop'}
}
catch {
Write-Host "Какая-то неисправность" -ForegroundColor RED
$PSItem.Exception
}
Переменная $PSItem хранит информацию о текущей ошибке, а глобальная переменная $Error будет хранит информацию обо всех ошибках. Так, например, я выведу одну и ту же информацию:
$Error[0].Exception
Создание отдельных исключений
Что бы обработать отдельную ошибку сначала нужно найти ее имя. Это имя можно увидеть при получении свойств и методов у значения переменной $Error:
$Error[0].Exception | Get-Member
Так же сработает и в блоке Catch с $PSItem:
Для вывода только имени можно использовать свойство FullName:
$Error[0].Exception.GetType().FullName
Далее, это имя, мы вставляем в блок Catch:
try {
'svchost111','svchost' | % {Get-Process -Name $PSItem -ErrorAction 'Stop'}
}
catch [Microsoft.PowerShell.Commands.ProcessCommandException]{
Write-Host "Произошла ошибка" -ForegroundColor RED
$PSItem.Exception
}
Так же, как и было описано выше мы можем усложнять эти блоки как угодно указывая множество исключений в одном catch.
Выброс своих исключений
Иногда нужно создать свои собственные исключения. Например мы можем запретить добавлять через какой-то скрипт названия содержащие маленькие буквы или сотрудников без указания возраста и т.д. Способов создать такие ошибки — два и они тоже делятся на критические и обычные.
Выброс с throw
Throw — выбрасывает ошибку, которая останавливает работу скрипта. Этот тип ошибок относится к критическим. Например мы можем указать только текст для дополнительной информации:
$name = 'AD.1'
if ($name -match '.'){
throw 'Запрещено использовать точки в названиях'
}
Если нужно, то мы можем использовать исключения, которые уже были созданы в Powershell:
$name = 'AD.1'
if ($name -like '*.*'){
throw [System.IO.FileNotFoundException]'Запрещено использовать точки в названиях'
}
Использование Write-Error
Команда Write-Error работает так же, как и ключ ErrorAction. Мы можем просто отобразить какую-то ошибку и продолжить выполнение скрипта:
$names = @('CL1', 'AD.1', 'CL3')
foreach ($name in $names){
if ($name -like '*.*'){
Write-Error -Message 'Обычная ошибка'
}
else{
$name
}
}
При необходимости мы можем использовать параметр ErrorAction. Значения этого параметра были описаны выше. Мы можем указать значение ‘Stop’, что полностью остановит выполнение скрипта:
$names = @('CL1', 'AD.1', 'CL3')
foreach ($name in $names){
if ($name -like '*.*'){
Write-Error -Message 'Обычная ошибка' -ErrorAction 'Stop'
}
else{
$name
}
}
Отличие команды Write-Error с ключом ErrorAction от обычных команд в том, что мы можем указывать исключения в параметре Exception:
Write-Error -Message 'Обычная ошибка' -ErrorAction 'Stop'
Write-Error -Message 'Исключение' -Exception [System.IO.FileNotFoundException] -ErrorAction 'Stop'
В Exception мы так же можем указывать сообщение. При этом оно будет отображаться в переменной $Error:
Write-Error -Exception [System.IO.FileNotFoundException]'Моё сообщение'
…
Теги:
#powershell
#ошибки