Czy instrukcje bash case mogą kaskadowo?

29

Próbuję zrobić coś takiego:

case $level in
    3)
        echo "Level Three"

    2)
        echo "Level Two"

    1)
        echo "Level one"
        ;;
esac

gdzie jeśli $ poziom = 3, wynik byłby wyprowadzony

Level Three
Level Two
Level One

podczas gdy jeśli poziom $ = 1, to wypisuje tylko

Level One

Ale kiedy próbuję, pojawia się błąd, syntax error near unexpected token ')'ponieważ nie uwzględniłem ;;.

Czy każdy inny język, który znam, pozwala na to, czy jest na to sposób w bash? Jakieś słowo kluczowe, które oznacza „teraz idź i zrób następny przypadek, jakby pasował”?

Benubird
źródło
2
Jeśli każdy znajomy język na to pozwala, musisz nauczyć się języków innych niż C i jego naśladowcy. Przełom w przypadku, gdy stwierdzenia są historycznym wypadkiem projektowym w C, który w jakiś sposób przetrwał w bardziej zasadniczych językach.
Gilles „SO- przestań być zły”

Odpowiedzi:

42

Musisz użyć ;&zamiast, ;;aby uzyskać awarię:

#! /bin/bash
foo() {
    case "$1" in
        3)
            echo "Level Three"
            ;&
        2)
            echo "Level Two"
            ;&
        1)
            echo "Level One"
            ;;
        a)
            echo "Level a"
            ;&
        b)
            echo "Level b"
            ;&
        c)
            echo "Level c"
            ;;
    esac
}
echo 3:
foo 3
echo 2:
foo 2
echo a:
foo a
3:
Level Three
Level Two
Level one
2:
Level Two
Level one
a:
Level a
Level b
Level c

Zobacz sekcję Konstrukcje warunkowe w dokumentacji bash.

Innym specjalnym znacznikiem jest ;;&:

powoduje, że powłoka testuje wzorce w następnej klauzuli, jeśli taka istnieje, i wykonuje dowolną powiązaną listę poleceń w przypadku pomyślnego dopasowania.

;; jest zawsze ostateczny, nie są testowane żadne dalsze wzory.

#! /bin/bash

foo() {
    case "$1" in
        *3*)
            echo "Level Three"
            ;;&
        *2*)
            echo "Level Two"
            ;;&
        *1*)
            echo "Level One"
            ;;&
    esac
}

echo 12:
foo 12
echo 13:
foo 13
echo 23:
foo 23
12:
Level Two
Level One
13:
Level Three
Level One
23:
Level Three
Level Two
Mata
źródło
18
Uwaga dotycząca przenośności: ta składnia nie jest POSIX. Pochodzi z kshi jest dostępny w ksh, bash(od 4,0, 2009) oraz zsh(od 3.1.2, 1997). ;;&jest specyficzny dla bash.
Stéphane Chazelas
4
Należy również pamiętać, że zshodpowiednikiem bash„s ;;&jest ;|(dodana w 4.3.3, 2007).
Stéphane Chazelas,