답변:
당신은 할 수 없습니다. case
넘어지는 방법 은 ;;
분리기를 ;&
(또는 ;;&
) 로 바꾸는 것 입니다. 그리고 그것을 if 안에 넣는 것은 구문 오류입니다.
전체 논리를 규칙적인 조건부로 작성할 수 있습니다.
if [ "$input" != "foo" ] || [ "$VAR" = 1 ]; then
one branch ...
else # $input = "foo" && $VAR != 1
another branch...
fi
if
.
당신의 논리를 재구성하는 것이 좋습니다 : 대신에 "fallthrough"코드를 함수에 넣으십시오 :
fallthrough() { echo 'fallthrough worked!'; }
for input in foo bar; do
for var in 1 2; do
echo "$input $var"
case $input in
foo)
if (( var == 1 )); then
echo "falling through"
fallthrough
else
echo "not falling through"
fi
;;
*) fallthrough;;
esac
done
done
출력
foo 1
falling through
fallthrough worked!
foo 2
not falling through
bar 1
fallthrough worked!
bar 2
fallthrough worked!
다음 스크립트는 $var
먼저 테스트한다는 의미에서 테스트를 "내부"로 전환 한 다음 에 따라 (을 사용 ;&
하여 case
) 폴 스루를 수행합니다 $input
.
여부의 질문 "를 위해 fallthrough을 수행"때문에 우리는이 작업을 수행에 정말에만 의존하는 $input
경우 $var
입니다 1
. 그것이 다른 가치라면, 실패를 할 것인지에 대한 질문은 요구 될 필요조차 없습니다.
#/bin/bash
input='foo'
var='1'
case $var in
1)
case $input in
foo)
echo 'perform fallthrough'
;&
*)
echo 'fallthough worked'
esac
;;
*)
echo 'what fallthrough?'
esac
또는없이 case
:
if [ "$var" -eq 1 ]; then
if [ "$input" = 'foo' ]; then
echo 'perform fallthrough'
fi
echo 'fallthough worked'
else
echo 'what fallthrough?'
fi
*)
. 내 +1이 이미 있습니다.
두 변수를 한 번에 테스트하십시오 (bash 4.0-alpha +).
#!/bin/bash
while (($#>1)); do
input=$1 VAR=$2
echo "input=${input} VAR=${VAR}"; shift 2
if [ "$VAR" = 1 ]; then new=1; else new=0; fi
case $input$new in
foo0) echo "do not perform fallthrough" ;;
foo*) echo "perform fallthrough" ;&
*) echo "fallthrough worked!" ;;
esac
echo
done
테스트 중 :
$ ./script foo 0 foo 1 bar baz
input=foo VAR=0
do not perform fallthrough
input=foo VAR=1
perform fallthrough
fallthrough worked!
input=bar VAR=baz
fallthrough worked!
깨끗하고 간단합니다.
테스트 된 값 ( $new
)에는 VAR을 부울 값으로 변환하기 위해 두 개의 가능한 값만 있어야하므로 if 절이있는 이유를 이해하십시오. VAR은 대한 다음 시험 부울,로 할 수있는 경우 0
(하지 1
의) case
과를 제거합니다 if
.
폴 스루 기본값을 설정할 수 있지만 조건이 충족되는 경우에만 코드가 실행되는 조건을 배치하십시오.
#!/bin/bash
input='foo'
var='1'
case $input in
foo)
echo "Do fall through"
;& #always fall through
*)
if [ $var = "1" ] #execute only if condition matches
then
echo "fallthrough took place"
fi
esac
그러나 ilkkachu가 제안한 것처럼 스위치 대신 조건을 사용할 수도 있습니다.
누군가가 코드를 이해하지 못한다고 불평하지 않는다면 두 조건의 순서를 간단히 바꿀 수 있습니다.
input="foo"
VAR="1"
if
case $input in
foo)
[ $VAR = "1" ]
;;
esac
then
echo "fallthrough worked!"
fi
또는:
input="foo"
VAR="1"
case $input in
foo)
[ $VAR = "1" ]
;;
esac &&
echo "fallthrough worked!"
간단하고 명확합니다 (적어도 나에게). case
실패 자체를 지원하지 않습니다. 하지만 당신은 대체 할 수 *)
와 &&
후 esac
는 다른 지점의 반환 값을 존중하기 위해.
4.0 에서 새로운 연산자 ;&
와 ;;&
연산자가 소개Bash
되었지만 비슷한 상황에서 유용 할 수 있지만 귀하의 경우에는 소용이 없다고 생각합니다. 이것은 무엇 man bash
이러한 연산자에 대해 말한다 :
만약 ;; 연산자가 사용되면 첫 번째 패턴 일치 후에 후속 일치가 시도되지 않습니다. ; 대신에; & 사용 다음 패턴 세트와 연관된 목록으로 계속 실행합니다. ;; 대신에 ;; & 사용 쉘이 명령문에서 다음 패턴 목록 (있는 경우)을 테스트하고 성공적인 일치시 연관된 목록을 실행합니다.
즉, ;&
통해 가을이며, 우리가에서 알고있는 C
및
;;&
차종이 bash
경우 남아있는 대신에서 돌아온 확인
case
완전히 차단합니다. /programming//a/24544780/3691891;;&
에서 실제 예제를 찾을 수 있습니다 .
그 존재는 말했다, 어느 쪽 ;&
도 ;;&
에 둘 다 갈 것 때문에 스크립트에 사용될 수있는 *)
것을 항상 실행됩니다.
다음 스크립트는 논리를 다시 정렬하지 않고 작동하고 원하는 것을 수행하지만 예제로만 고려하고 절대 의존하지 마십시오. 너무 약합니다. 나는 여기 에서 아이디어를 얻었습니다 .
#!/usr/bin/env bash
function jumpto
{
label=$1
cmd=$(sed -n "/$label:/{:a;n;p;ba};" "$0" | grep -v ':$')
cmd=$(echo "$cmd" | sed 's,;;,,')
cmd=$(echo "$cmd" | sed 's,esac,,')
eval "$cmd"
}
input="foo"
VAR="1"
case $input in
foo)
if [ $VAR = "1" ]; then
printf "perform fallthrough\n"
jumpto ft
else
printf "do not perform fallthrough\n"
fi
;;
*)
ft:
echo "fallthrough worked!"
;;
esac
jumpto
함수 에서 반환하고 그 뒤에 오는 모든 것을 실행합니다. 이 블록의 실행 후에 계속에 해당한다는 사실 ft:
과 ;;
때문에 우연 jumpto
(가) 뛰어-로서 블록 같은 복잡한 명령의 마지막 명령이다.
if [ $VAR -eq 1 ]; then
코드의 일부 에서 다른 곳으로 이동하려고*)
합니까? 그것이 실패라고 불리는 것과 완전히 다르기 때문에 질문 문구를 약간 오도하게 만듭니다.