Обробка винятків у сценаріях оболонки?


77

Я шукаю механізм обробки винятків у сценарії оболонки. Чи існує якийсь спроб, зловити еквівалентний механізм у сценарії оболонки?



Відповіді:


123

Насправді не існує try/catchin bash (я припускаю, що ви використовуєте bash), але ви можете досягти досить подібної поведінки за допомогою &&або ||.

У цьому прикладі ви хочете запустити, fallback_commandякщо a_command не вдається (повертає ненульове значення):

a_command || fallback_command

І в цьому прикладі ви хочете виконати, second_commandякщо a_command успішно (повертає 0):

a_command && second_command

Їх можна легко змішати, використовуючи допоміжну оболонку, наприклад, буде виконана наступна команда a_command, якщо вона буде успішною, вона буде запущенаother_command , буде виконана , але якщо a_commandабо other_commandне вдасться, fallback_commandбуде виконана:

(a_command && other_command) || fallback_command

14
Бонус: якщо ви хочете "нарешті", як поведінку, використовуйте no-op (: у bash) так: (a_command || : )і наступний рядок буде працювати так, ніби помилки не сталося a_command.
BT

Чудово! Врятував мені багато кодування.
Mrinal

Не зовсім тому, що семантика нарешті полягає в тому, що вона працює незалежно від стану винятку.
FP Вільно

12

Структура if / else та коди виходу можуть допомогти вам підробити деякі з них. Це має працювати в Bash або Bourne (sh).

if foo ; then
else
  e=$?        # return code from if
  if [ "${e}" -eq "1"]; then
    echo "Foo returned exit code 1"
  elif [ "${e}" -gt "1"]; then
    echo "Foo returned BAD exit code ${e}"
  fi
fi

1
if foo ; then elseможна спростити if ! foo ; then, +1 у будь-якому випадку.
jlliagre

2
@jiliagre Це не працює. "! foo" інвертує $? від 0 до 1 і! 0 до 0.
brightlancer

7
{
    # command which may fail and give an error 
} || {
   # command which should be run instead of the above failing      command
}

6
Можливо, це було б, betterякби ви пояснили тому, хто задає питання, псевдокод, який ви публікуєте, а не просто блок загадкового коду, який вони можуть не зрозуміти. Якщо дитина цього не може зрозуміти, це не є гарною відповіддю.
Йокай

3

Ось дві прості функції bash, які дозволяють обробляти події в bash:

Ви можете використовувати його для базової обробки винятків так:

onFoo(){
  echo "onFoo() called width arg $1!"
}  

foo(){
  [[ -f /tmp/somefile ]] || throw EXCEPTION_FOO_OCCURED "some arg"
} 

addListener EXCEPTION_FOO_OCCURED onFoo

Обробка винятків за допомогою блоків try / catch не підтримується в bash, однак, ви можете спробувати подивитися на структуру BANGSH, яка її підтримує (це трохи як jquery для bash).

Тим НЕ менше , exceptionhandling без каскадного Try / Catch-блоки схоже на eventhandling , що це можливо практично будь-якому мовою з масивом-підтримкою.

Якщо ви хочете, щоб ваш код був приємним і охайним (без деталізації if / else), я б рекомендував використовувати події.

Пропозиція, яку рекомендує MatToufoutu (використовуючи || та &&), не рекомендується для функцій, але добре для простих команд . (див. BashPitfalls про ризики)


0

Використовуйте наступне, щоб правильно обробити помилку, де error_exit - це функція, яка приймає один аргумент. Якщо аргумент не передано, він видасть невідому помилку з LineNo, де насправді відбувається помилка. Будь ласка, експериментуйте перед тим, як насправді використовувати для виробництва -

#!/bin/bash

PROGNAME=$(basename $0)

error_exit()

{

    echo "${PROGNAME}: ${1:-"Unknown Error"}" 1>&2
    exit 1
}

echo "Example of error with line number and message"
error_exit "$LINENO: An error has occurred."
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.