Linux, если Elif еще не удается

1

Я пытаюсь найти, если точка монтирования 1 доступна, и если нет, смонтировать ее. Если точка монтирования 1 не пройдена, смонтировать 2-ю. Если это не удается, отобразите сообщение об ошибке.

Вот код:

mount > /tmp/log;
if grep -ohw 123.456.789 /tmp/log >/dev/null; then echo -e " STACK MOUNT \e[1;33mALREADY\e[00m AVAILABLE \e[1;33mPASSED\e[00m ";
elif mount -t nfs -o ro,nolock 123.456.789:/opt/media/ /mount/stack &>/dev/null; then mount > /tmp/log;
if grep -ohw 123.456.789 /tmp/log >/dev/null; then echo -e " STACK MOUNT AVAILABLE \e[1;33mPASSED\e[00m ";
elif mount -t nfs -o ro,nolock 223.456.789:/opt/media/ /mount/stack &>/dev/null; then mount > /tmp/log;
if grep -ohw 223.456.789 /tmp/log >/dev/null; then echo -e " STACK MOUNT AVAILABLE \e[1;33mPASSED\e[00m ";
else echo -e " STACK MOUNT NOT AVAILABLE          \e[00;31mFAILED\e[00m"; fi; fi; fi | tee -a /tmp/log

Если какая-либо из точек крепления 2 установлена, результат хороший. Проблема заключается в том, что когда ни одна из точек монтирования не смонтирована, оператор FAILURE не отображается.

user2692634
источник

Ответы:

2

Сообщение об ошибке не отображается, потому что этот оператор вложен в одно слишком много предложений «then». Я предлагаю упростить логику следующим образом:

is_mounted() {
    mount | grep -qohw "$1
}


{
pass=
for ip in  123.456.789  223.456.789
do
    if is_mounted "$ip"
    then
        echo -e " STACK MOUNT \e[1;33mALREADY\e[00m AVAILABLE \e[1;33mPASSED\e[00m "
        pass=1
        break
    fi
    mount -t nfs -o ro,nolock "$ip:/opt/media/" /mount/stack &>/dev/null
    if is_mounted "$ip"
    then
        echo -e " STACK MOUNT AVAILABLE \e[1;33mPASSED\e[00m "
        pass=1
        break
    fi
done
[ "$pass" ] || echo -e " STACK MOUNT NOT AVAILABLE          \e[00;31mFAILED\e[00m"
} | tee /tmp/log
mount >>/tmp/log

В исходном коде /tmp/logон обновляется tee -aодновременно с тем, что он перезаписывается mount. Это, вероятно, не будет надежным. Код выше избегает этого.

PS Как отлаживать: если код "зависает", это, вероятно, потому что mountзависает при попытке монтирования NFS. Чтобы выяснить это наверняка, (a) добавьте некоторые диагностические echoоператоры, (b) отобразите mountвыходные данные, если таковые имеются (они были удалены в приведенном выше коде), и (c) добавьте -vопцию, mountчтобы сделать их подробными. Можно также удалить teeоператор, чтобы не возникало проблем с выходной буферизацией. Таким образом, попробуйте:

is_mounted() {
    mount | grep -qohw "$1
}

{
pass=
echo "Starting to loop over IP addresses"
for ip in  139.41.170.10 197.21.82.10 139.41.170.11 197.21.82.11 139.31.125.11
do
    echo "Testing to see if $ip is mounted"
    if is_mounted "$ip"
    then
        echo -e " STACK MOUNT \e[1;33mALREADY\e[00m AVAILABLE \e[1;33mPASSED\e[00m "
        pass=1
        break
    fi
    echo "Attempting to mount $ip"
    mount -v -t nfs -o ro,nolock "$ip:/opt/media/" /mount/stack
    echo "mount finished with exit code=$?"
    if is_mounted "$ip"
    then
        echo -e " STACK MOUNT AVAILABLE \e[1;33mPASSED\e[00m "
        pass=1
        break
    fi
    echo "Not able to mount $ip"
done
echo "Completed loop over IP addresses with pass=$pass"
[ "$pass" ] || echo -e " STACK MOUNT NOT AVAILABLE          \e[00;31mFAILED\e[00m"
}
mount >>/tmp/log

PPS Обработка неработающих хостов: при работе с монтируемыми NFS mountкоманда обычно имеет очень длительный тайм-аут.на хостах (более 2 минут в моей системе). Напротив, pingможет обнаружить, если хост не работает в считанные секунды. Таким образом, чтобы избежать длительного mountтаймаута, сначала можно проверить, используется ли хост ping. Для этого замените mount -t nfs...строку на:

ping -c2 "$ip" >/dev/null && mount -t nfs -o ro,nolock "$ip:/opt/media/" /mount/stack &>/dev/null

Это, конечно, предполагает, что вы находитесь в сети, которая позволяет хостам отвечать на эхо-запросы.

John1024
источник
есть ли какие-либо ограничения на использование IP-адресов в коде «для ip in», я пытался проверить оператор FAILURE, использовал эти ip-ы 139.41.170.10, 197.21.82.10, 139.41.170.11, 197.21.82.11, 139.31.125.11, есть ли IP формат для подражания.
user2692634
@ user2692634 Вы можете ввести столько IP-адресов, сколько умещается в строке. Просто разделяйте их только пробелами (без запятых и других знаков препинания).
John1024
Согласна с тобой, но не получай никакого выхода, просто повесь.
user2692634
@ user2692634 Я думаю, что он зависал mountпри попытке монтирования NFS. Однако, чтобы быть уверенным, пожалуйста, попробуйте новый код, который я добавил к посту. Он добавляет несколько функций отладки. Позвольте мне знать, что происходит.
John1024
Вы были правы, что он завис во время монтирования - Начинаем циклически перебирать IP-адреса - Проверяем, смонтировано ли 139.41.170.10 - Попытка смонтировать 139.41.170.10. Также я использовал set -x и set + x, чтобы увидеть, где именно происходит сбой, и обнаружил, что он зависает при монтировании чего-то вроде этого - code - "set -x" - кода для отладки - "set + x" code Отладка журналов ++ pass = ++ echo 'Начало цикла по IP-адресам' .... Попытка смонтировать 139.41.170.10 ++ mount -v -t nfs -o ro, nolock 139.41.170.10:/opt/media/ / mount / stack нет ответа после этого висит.
user2692634
1

Это сводится к «фи» размещения. Если вы расположите свой сценарий более формально, это станет более очевидным - первый блок 'if' / 'elif' не будет завершен до третьего 'fi'. Из вашего описания требования я бы ожидал «if / elif / fi, if / elif / fi, if / else / fi».

Как отметил Слартибартфаст, может быть более читабельным / обслуживаемым, чтобы реструктурировать его в единую цепочку if / elif / elif ... / else / fi, но, как вы ее структурировали, вы можете исправить это, перемещая 'fi' после и оставляя все остальное как есть.

Текущий код с форматированием:

mount> / tmp / log;
if grep -ohw 123.456.789 / tmp / log> / dev / null;
затем
    echo -e "STACK MOUNT \ e [1; 33mREADY \ e [00m ДОСТУПНО \ e [1; 33mPASSED \ e [00m");
elif mount -t nfs -o ro, nolock 123.456.789: / opt / media / / mount / stack &> / dev / null;
затем
    mount> / tmp / log;
    if grep -ohw 123.456.789 / tmp / log> / dev / null;
    затем
        echo -e "STACK MOUNT AVAILABLE \ e [1; 33mPASSED \ e [00m");
    elif mount -t nfs -o ro, nolock 223.456.789: / opt / media / / mount / stack &> / dev / null;
    затем
        mount> / tmp / log;
        if grep -ohw 223.456.789 / tmp / log> / dev / null;
        затем
            echo -e "STACK MOUNT AVAILABLE \ e [1; 33mPASSED \ e [00m");
        еще
            echo -e "МОНТАЖ СТЕКА НЕ ДОСТУПЕН \ e [00; 31mFAILED \ e [00m");
        Fi;
    Fi;
фи | тройник -a / tmp / log

Как видно из рисунка, если исходное монтирование отсутствует, а первая команда монтирования завершается неудачно, то мы выходим из всего блока 'if' - невозможно выполнить ни один из последних кодов.

tenorkev
источник
0

Слишком много если

if A; then B
elif C; then D
elif E; then F
else G
fi

Надеюсь, это поможет.

Кроме того, для задач, которые необходимо выполнить последовательно, чтобы убедиться, что все задачи завершены успешно, вы можете попробовать объединить задачи с помощью &&. Это приведет к тому, что команды будут выполняться с остановкой последовательности, только если (и когда) произойдет сбой, и будет возвращен код завершения последнего выполнения команды:

mount squiggle && mount > /tmp/log && grep squiggle >/dev/null && echo -e "squiggle";

Приведенная выше команда попытается mount squiggleвыйти с ошибкой / ошибкой, если нет. В случае успеха он запустит команду монтирования с выводом в / tmp / log. Если эта команда не выполнена, она завершится с ошибкой. В противном случае команда grep будет запущена ....

Слартибартфаст
источник