Bisakah bash statement case cascade?

29

Saya mencoba melakukan sesuatu seperti ini:

case $level in
    3)
        echo "Level Three"

    2)
        echo "Level Two"

    1)
        echo "Level one"
        ;;
esac

di mana jika $ level = 3, itu akan ditampilkan

Level Three
Level Two
Level One

sementara jika $ level = 1, itu hanya akan menghasilkan

Level One

Tetapi ketika saya mencobanya, saya mendapatkan kesalahan syntax error near unexpected token ')'karena saya tidak memasukkan ;;.

Setiap bahasa lain yang saya tahu memungkinkan ini, apakah ada cara untuk melakukannya di bash? Semacam kata kunci yang berarti "sekarang lanjutkan dan lakukan huruf besar berikutnya seolah-olah cocok"?

Benubird
sumber
2
Jika setiap bahasa yang Anda kenal memungkinkan ini, Anda perlu mempelajari bahasa selain C dan penirunya. Kesalahan dalam pernyataan kasus adalah kecelakaan desain historis di C yang entah bagaimana bertahan dalam bahasa yang lebih berprinsip.
Gilles 'SO- stop being evil'

Jawaban:

42

Anda perlu menggunakan ;&alih-alih ;;mendapatkan perilaku jatuh:

#! /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

Lihat bagian Konstruksi Bersyarat dari dokumentasi bash.

Penanda khusus lainnya adalah ;;&, yang:

menyebabkan shell untuk menguji pola dalam klausa berikutnya, jika ada, dan menjalankan daftar perintah yang terkait pada kecocokan yang berhasil.

;; selalu final, tidak ada pola lebih lanjut yang diuji.

#! /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
Tikar
sumber
18
Catatan Portabilitas: sintaks yang bukan POSIX. Itu berasal dari kshdan tersedia di ksh, bash(sejak 4.0, 2009) dan zsh(sejak 3.1.2, 1997). ;;&spesifik untuk bash.
Stéphane Chazelas
4
Juga catatan bahwa zshsetara dengan bash's ;;&adalah ;|(ditambahkan dalam 4.3.3, 2007).
Stéphane Chazelas