Обработка исключений в скриптах bash - PullRequest
0 голосов
/ 07 марта 2019

У меня есть скрипт bash (исполняемый Jenkins), который вызывает в одной точке

local STATUS=$($SERVER_DIR/bin/jboss-cli.sh --controller=$WILDFLY_CONTROLLER --connect --user=$ADMIN_USER --password=$ADMIN_PW command=:shutdown --timeout=$JBOSSTIMEOUT);

Единственная цель в этом фрагменте - отключить работающий процесс wildfly.Если вызов сам по себе был успешным, но по какой-то причине wildfly не был прерван, я также добавил еще одну проверку, которая выполняется через несколько секунд

SERVER_PID=`ps aux | grep $SERVER_DIR | grep 'wildfly.xml' | grep -v grep | tr -s ' ' | cut -d ' ' -f 2`;
if [[ ! -z $SERVER_PID ]] ; then
        kill -9 $SERVER_PID;
    fi

Однако время от времени - я не мог выяснить, под какимобстоятельства - фрагмент ведет себя не так, как ожидалось.

Тип проблемы 1)

Вызов jboss-cli.sh приводит к исключению

> 2019-02-27_22-05-17 [INFO] Trying to stop wildfly service with jboss-cli.sh
/opt/wildfly/bin/jboss-cli.sh --controller=10.0.1.1:9990 --connect --user=XXXX --password=XXXX command=:shutdown --timeout=120
org.jboss.as.cli.CliInitializationException: Failed to connect to the controller
    at org.jboss.as.cli.impl.CliLauncher.initCommandContext(CliLauncher.java:278)
    at org.jboss.as.cli.impl.CliLauncher.main(CliLauncher.java:241)
    at org.jboss.as.cli.CommandLineMain.main(CommandLineMain.java:34)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.jboss.modules.Module.run(Module.java:312)
    at org.jboss.modules.Main.main(Main.java:460)
Caused by: org.jboss.as.cli.CommandLineException: The controller is not available at 10.0.1.27:9990
    at org.jboss.as.cli.impl.CommandContextImpl.tryConnection(CommandContextImpl.java:1028)
    at org.jboss.as.cli.impl.CommandContextImpl.connectController(CommandContextImpl.java:840)
    at org.jboss.as.cli.impl.CommandContextImpl.connectController(CommandContextImpl.java:819)
    at org.jboss.as.cli.impl.CliLauncher.initCommandContext(CliLauncher.java:276)
    ... 8 more
Caused by: java.io.IOException: java.net.ConnectException: JBAS012144: Could not connect to http-remoting://10.0.1.1:9990. The connection timed out
    at org.jboss.as.controller.client.impl.AbstractModelControllerClient.executeForResult(AbstractModelControllerClient.java:129)
    at org.jboss.as.controller.client.impl.AbstractModelControllerClient.execute(AbstractModelControllerClient.java:71)
    at org.jboss.as.cli.impl.CommandContextImpl.tryConnection(CommandContextImpl.java:1005)
    ... 11 more
Caused by: java.net.ConnectException: JBAS012144: Could not connect to http-remoting://10.0.1.1:9990. The connection timed out
    at org.jboss.as.protocol.ProtocolConnectionUtils.connectSync(ProtocolConnectionUtils.java:119)
    at org.jboss.as.protocol.ProtocolConnectionManager$EstablishingConnection.connect(ProtocolConnectionManager.java:256)
    at org.jboss.as.protocol.ProtocolConnectionManager.connect(ProtocolConnectionManager.java:70)
    at org.jboss.as.protocol.mgmt.FutureManagementChannel$Establishing.getChannel(FutureManagementChannel.java:204)
    at org.jboss.as.cli.impl.CLIModelControllerClient.getOrCreateChannel(CLIModelControllerClient.java:169)
    at org.jboss.as.cli.impl.CLIModelControllerClient$2.getChannel(CLIModelControllerClient.java:129)
    at org.jboss.as.protocol.mgmt.ManagementChannelHandler.executeRequest(ManagementChannelHandler.java:117)
    at org.jboss.as.protocol.mgmt.ManagementChannelHandler.executeRequest(ManagementChannelHandler.java:92)
    at org.jboss.as.controller.client.impl.AbstractModelControllerClient.executeRequest(AbstractModelControllerClient.java:236)
    at org.jboss.as.controller.client.impl.AbstractModelControllerClient.execute(AbstractModelControllerClient.java:141)
    at org.jboss.as.controller.client.impl.AbstractModelControllerClient.executeForResult(AbstractModelControllerClient.java:127)
    ... 13 more
packet_write_wait: Connection to XXX.XXX.XXX.XXX port 22: Broken pipe
Build step 'Execute shell' marked build as failure

, которое, в свою очередь, прерывает скрипт bash итаким образом работа Дженкинса.Итак, вопрос 1: как я могу перехватить исключения и убедиться, что скрипт bash обработан и wildfly завершен с помощью kill-switch.

Тип проблемы 2)

иногда вызов зависает иконсоль показывает только

2019-02-27_22-05-17 [INFO] Попытка остановить службу wildfly с помощью jboss-cli.sh / opt / wildfly / bin / jboss-cli.sh --controller = 10.0.1.1: 9990 --connect --user = XXXX --password = XXXX команда =: shutdown --timeout = 120

Кажется, что свойство timeoutиз Jboss не работает должным образом.Итак, вопрос 2: как я могу убедиться, что звонок завершен и не выполняется / ждет бесконечно?

Спасибо, Ричард

1 Ответ

0 голосов
/ 07 марта 2019

Хотя это не совсем то же самое, поведение в стиле исключений можно до некоторой степени эмулировать в bash с помощью trap.

Прежде чем вы попробуете это, лучше понять их по-настоящему, поэтому я настоятельно рекомендую вам руководство по Bash , в особенности концепцию кодов выхода , проверенную с помощью условных выражений .

Я обычно использую что-то вроде этого:

trap 'echo >&2 "ERROR in $BASH_SOURCE at line $LINENO, Aborting"; exit $LINENO;' ERR

ERR (обычно без учета регистра) - это специальный триггер в bash, который вызывает любой код ловушки, установленный для него, всякий раз, когда из выполненной команды возвращается ошибка uncaught . Например:

$: trap 'echo OW' err
$: false
OW

false всегда возвращает код выхода 1, поэтому он вызывает ловушку, если не пойман, например:

$: trap 'echo OW' err
$: false || echo nope
nope

|| упоминается вместе с && в нижней части ссылки на условные выражения, но в основном
&& вычисляет его правое выражение, если левое выражение возвращает true - 0 состояние выхода. || вычисляет его правое выражение, если левое выражение возвращает false - ненулевое состояние выхода. Либо из этих отлавливает (потребляет) ошибку, не давая ей активировать ловушку, как и большинство любых условных проверок состояния выхода.

Итак - предположим, файл xmp с содержимым «Hello» и вышеуказанной ловушкой на месте.

$: echo Hello>xmp                                  # create simple file
$: grep foo xmp                                    # uncaught fail will trigger trap
OW
$: grep Hello xmp                                  # success doesn't trigger trap
Hello
$: if grep foo xmp; then echo ok; else echo no; fi # caught exception doesn't trigger trap
no
$: grep Hello xmp && echo ok || echo no            # success, no trigger
Hello
ok
$: grep foo xmp && echo ok || echo no              # caught, no trigger
no
$: grep foo xmp || false                           # LHS caught, RHS triggers trap
OW
$: grep Hello xmp || false                         # LHS doesn't trigger RHS, no error, no trigger
Hello
$: grep foo xmp ||:                                # explicit ignore, : is an alieas for true
# WATCH OUT FOR THIS ONE -
$: grep foo xmp && echo ok                         # CHECKED, so *caught*
# note no trigger on the last one, because it was tested, even if not explicitly handled...

Это может или не может вам сильно помочь, но всегда приятно иметь постоянное поведение для любой необнаруженной ошибки, а затем явно обрабатывать все, что, как вы знаете, может дать сбой, но что вы можете исправить, или это не совсем вопрос.

Просто убедитесь, что вы понимаете, что он делает и как работает, чтобы вас это не удивляло. Всегда проверяйте, что он делает то, что вы ожидаете.

...