Как говорится: «Дай человеку рыбу — он будет сыт целый день. Научи его пользоваться Linux и он будет сыт этим дерьмом всю оставшуюся жизнь»

Источник: оригинал в Telegram

Привет друзья. Давай разберем очередную башболячку, с которой многие сталкиваются. Нет, это не условные хреновины eq/gt, но очень похожи.

Есть Bash скрипт:

#!/bin/bash

case $1 in
    3)
        echo "Уровень 3"
        ;&
    2)
        echo "Уровень 2"
        ;&
    1)
        echo "Уровень 1"
        ;;
    a)
        echo "Уровень A"
        ;&
    b)
        echo "Уровень B"
        ;&
    c)
        echo "Уровень C"
        ;;
esac

Что непонятного в этом скрипте? Правильно, где-то используется конструкция «;&», где-то «;;» а еще может быть «;;&».

Ватафак? Поехали разбираться.

Все эти конструкции влияют на логику работы оператора case.

И, как обычно, этот синтаксис вводит в заблуждение, а порой даже разрывает жопы у бывалых инженеров. Но на самом деле все просто.

Запускаем скрипт с параметрами:

./bashdays.sh 3

Получаем:

Уровень 3
Уровень 2
Уровень 1

Понял что произошло? Скрипт нашел тройку в параметре и отработал до символа «;;», выведя на экран все 3 кейса. То есть получается символ «;&» отработал как «ДАВАЙ ДАЛЬШЕ», а символ «;;» как BREAK.

Аналогично если запустим так:

./bashdays.sh a

То получим второй кусок кейса, который выведет:

Уровень A
Уровень B
Уровень C

Просто? Просто! Погнали дальше.

Если забить хуй в параметре например «двойку», то получим такое:

Уровень 2
Уровень 1

Уровень 3 уже пролетает как фанера над Парижем.

Роман Шубин
Роман Шубин
CEO & CTO, Главред в «Цифровой улей»
Задать вопрос
С этими кейсами нужно быть особо аккуратным, так как это тонкий лед и нужно не запутаться в логике. Есть еще «;;&» но он почти идентичен «;&», про него чуть ниже.

У меня с этим вечная проблема, но я нашел годный лайфхак — сначала рисую логику на бумажке и потом по ней уже пишу скрипт. Работает кстати хорошо и для всяких if-ов.

Получается так:

;; - Обозначение конца блока для текущего случая case. Когда интерпретатор bash встречает «;;» он завершает выполнение текущего блока и переходит к следующему ветвлению (если оно есть).

;& - Обозначение «проваливания» (fallthrough) в case операторе. Когда интерпретатор bash встречает «;&», он продолжает выполнение следующего блока кода без остановки, даже если условие не соответствует.

;;& - аналогично «;&», за исключением того, что после выполнения кода текущего случая, интерпретатор также завершает текущий блок кода и продолжает выполнение следующего случая.

;) а это просто подмигивающий смайлик.

Можно кстати еще аналог wildcard использовать в case:

case $1 in
ba*)
    echo "все что начинается на ba"
;&

Так, чисто для развития, мож пригодится когда-нибудь.

С пятницей, всем хороших предстоящих выходных, берегите себя!