«Bash» не поддерживает команду «try/catch». Однако есть и другие способы применения его функций, такие как операторы «if/else», операторы «OR», команда «trap» или флаг «-x».
«try-catch» — это программный термин, используемый для обработки исключений. Проще говоря, блок «try» пытается выполнить какую-то работу, и если есть ошибка, например, файл не найден, он выдает исключение, которое может быть обработано в блоке «catch».
В этой статье рассматриваются подходы, которые можно использовать вместо команды «try/catch».
Проверка «exit status»
Все команды генерируют однозначное значение («0» для «истина» и «1» для «ложь»). Это делается с помощью опции «set -e». Этот параметр предлагает Bash немедленно выйти, если какая-либо команда в сценарии завершается с ненулевым кодом. В приведенном ниже примере скрипт устанавливает Firefox в систему. После успешного выполнения отображается сообщение «Command succeeded» следующим образом:
#!/bin/bash set -e sudo apt install firefox echo "Command succeeded"
Перед его выполнением обязательно дайте ему права на выполнение (приведенный выше скрипт называется «script.sh») с помощью команды chmod с флагом +x :
sudo chmod +x script.sh
Выполненная выше команда подтверждает, что права на выполнение были предоставлены файлу «script.sh». Однако, чтобы выполнить его, примените следующую команду:
bash script.sh
andreyex@ubuntu: $ bash script.sh Reading package lists… Done Building dependency tree… Done Reading state information… Done firefox is already the newest version (1:1snap1-Oubuntu2). The following packages were automatically installed and are no longer r libpython2-stdlib libpython2.7-minimal libpython2.7-stdlib python-pkg python2-minimal python2.7 python2.7-minimal Use 'sudo apt autoremove' to remove them. 0 upgraded. 0 newly installed, 0 to remove and 79 not upgraded. Command succeeded andreyex@ubuntu: $
Глядя на изображение выше, становится очевидным, что команда выполнена успешно, поскольку отображается сообщение «Command succeeded». Может быть несколько сценариев, в которых вы можете использовать команду echo для проверки «exit status» сразу после выполнения команды.
Как заставить команду «trap» работать как TRY CATCH?
Команда «trap» работает на основе сигналов, посылаемых ей ОС или пользователем (нажатием «CTRL+C», чтобы прервать программу). Это триггер, который является ответом на определенную команду. Например, приведенный ниже скрипт работает до тех пор, пока пользователь не нажмет «CTRL+C». После нажатия он отобразит сообщение «trap worked» и заснет на «5» секунд, прежде чем вернуть управление пользователю:
#!/bin/bash trap 'echo "trap worked"' INT ( trap '' INT sleep 5 echo "done" ) & wait for
Приведенный выше скрипт называется «script.sh. Выполним его для просмотра результатов:
bash script.sh
andreyex@ubuntu: $ bash script.sh Ctrap worked andreyex@ubuntu: $ done AC CTRL+C is pressed andreyex@ubuntu: $
В приведенном выше терминале видно, что когда мы нажимали «CTRL + C», он напечатал «trap worked», и может быть несколько сценариев, в которых ее можно использовать. Например, в приведенном ниже сценарии, когда служба запущена, она остановит и перезапустит эту службу. Предположим, что в данном случае сервисом является «mysql»:
#!/bin/bash function finish { echo "service started" sudo service mysql start } trap finish EXIT echo "service stopped" sudo service mysql stop
Скрипт называется «script.sh». Давайте выполним его, чтобы просмотреть вывод:
bash- скрипт.sh
andreyex@ubuntu: $ bash script.sh service stopped service started andreyex@ubuntu:-$
Как видно из приведенного выше терминала, он сначала останавливает службу, а затем запускает ее снова. Если вы хотите запустить службу сразу после ее остановки, нажмите «CTRL+C»:
bash script.sh
andreyex@ubuntu: $ bash script.sh service stopped Cservice started Candreyex@ubuntu: -$
Приведенные выше примеры похожи на «try/catch» в том смысле, что выполнение сценария с несколькими командами занимает много времени. Вы можете удалить его с помощью сочетания клавиш «CTRL+Z», но он не будет отображать сообщение, напечатанное с помощью команды «echo». Но когда используется команда trap, легче определить, какая команда работает нормально, а какая нет.
Как отследить вывод с помощью флага -x в Bash?
Флаг «-x» используется для отладки сценария bash. Он интерпретирует каждую выполняемую строку и отображает все в сценарии. Чтобы использовать его, добавьте предшествующий «-x» при выполнении команды, как показано ниже:
bash -x script.sh
andreyex@ubuntu: $ bash -x script.sh + trap finish EXIT + echo 'service stopped' service stopped +sudo service mysql stop +finish + echo 'service started' service started + sudo service mysql start andreyex@ubuntu: $
На приведенном выше изображении параметры скрипта отображаются в том же формате, в котором он выполняется.
Как принудительно выйти при обнаружении ошибки в Bash?
«Set» используется с «errexit» или «-e» в bash для выхода. Что он делает, так это автоматическое завершение команды при возникновении ошибки. Этот параметр указывает «Bash» немедленно выйти из сценария, когда любая команда возвращает ненулевой статус выхода, что указывает на ошибку.
Ниже приведен пример сценария, в котором обновляются системные репозитории, устанавливается Python, клонируется git, устанавливаются требования к Python и, наконец, соответственно запускается сервер:
#!/bin/bash sudo apt-get update sudo apt install git curl python3-pip git clone https://github.com/example/repo.git pip3 install -r requirements.txt python3 app.py
Он называется «script.sh». Чтобы выполнить его, примените указанную ниже команду, как обсуждалось:
bash script.sh
andreyex@ubuntu: $ bash script.sh Hit:1 http://security.ubuntu.com/ubuntu jammy-security InRelease Hit:2 http://us.archive.ubuntu.com/ubuntu jammy InRelease Hit:3 http://us.archive.ubuntu.com/ubuntu jammy-updates InRelease Hit:4 https://ppa.launchpadcontent.net/adiscon/v8-stable/ubuntu jammy InRelease Hit:5 http://us.archive.ubuntu.com/ubuntu jammy-backports InRelease Reading package lists… Done Reading package lists… Done Building dependency tree… Done Reading state information… Done curl is already the newest version (7.81.0-1ubuntu1.10). git is already the newest version (1:2.34.1-1ubuntu1.8). python3-pip is already the newest version (22.0.2+dfsg-1ubuntu0.2). The following packages were automatically installed and are no longer required: libpython2-stdlib libpython2.7-minimal libpython2.7-stdlib python-pkg-resources python-setuptools python2 python2-minimal python2.7 python2.7-minimal Use 'sudo apt autoremove' to remove them. 0 upgraded, 0 newly installed, 0 to remove and 92 not upgraded. Cloning into 'repo'… Username for ' https://github.com ': test Password for 'https:// test@github.com ':
Предоставленные выше «Username» и «Password» для GitHub неверны, что вызовет ошибку, приводящую к завершению скрипта, указанному ниже:
Username for https://github.com ': test Password for "https:// test@github.com ': remote: Support for password authentication was removed on August 13, 2021. remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote- repositories#cloning-with-https-urls for information on currently recommended modes of authentic fatal: Authentication failed for ' https://github.com/example/repo.git/ ' Defaulting to user installation because normal site-packages is not writeable Coul dir python3: can't open file '/home/andreyex/app.py': [Errno 2] No such file or directory andreyex@ubuntu: $ ents.txt
Как видно выше, сценарий немедленно завершается при появлении ошибки.
Заключение
Скрипты bash не поддерживают оператор «try/catch», как большинство других языков программирования. Однако есть и другие альтернативы для применения той же функциональности, такие как проверка «exit status», применение команды «trap» или отслеживание вывода с помощью флага «-x», что также может быть полезно. Кроме того, скрипт может быть немедленно прерван при появлении ошибки с помощью команды «set -e». В этом руководстве обсуждалось состояние команды «try/catch» в bash и ее альтернативы.