및 와 같은 expr1
두 가지 조건식을 고려하십시오 . 우리는 이것을 여러 가지 방법으로 쓸 수 있습니다. 여기에는 두 가지 가능성이 있습니다expr2
$i -eq $j
$k -eq $l
bash
[[ expr1 || expr2 ]]
[[ expr1 ]] || [[ expr2 ]]
나는 두 번째 제안이 선호되어야 한다는 제안을 여기에서 볼 수 있다고 확신하지만 이를 뒷받침하는 증거를 찾을 수 없습니다.
차이가 없는 것으로 보이는 샘플 스크립트는 다음과 같습니다.
for i in 0 1
do
for j in 0 1
do
for k in 0 1
do
for l in 0 1
do
if [[ $i -eq $j || $k -eq $l ]]; then printf "1-yes\t"; else printf "1-no\t"; fi
if [[ $i -eq $j ]] || [[ $k -eq $l ]]; then printf "2-yes\n"; else printf "2-no\n"; fi
done
done
done
done
출력은 두 조건부 구문이 동일한 결과를 생성한다는 것을 보여줍니다.
1-yes 2-yes
1-yes 2-yes
1-yes 2-yes
1-yes 2-yes
1-yes 2-yes
1-no 2-no
1-no 2-no
1-yes 2-yes
1-yes 2-yes
1-no 2-no
1-no 2-no
1-yes 2-yes
1-yes 2-yes
1-yes 2-yes
1-yes 2-yes
1-yes 2-yes
한 구조를 다른 구조보다 사용하면 이점이 있습니까?
보너스 포인트의 경우 동일한 질문이지만 ||
여러 조건에 사용 및 일반화되었습니다 &&
. 예를 들어, [[ expr1 && expr2 || expr3 ]]
.
답변1
내 생각에 당신이 보는 조언은 POSIX에 대한 것입니다.쉿및/또는 ksh에 나타나는 구성(팁을 제공한 Stéphane Chazelas에게 감사) 보다는 명령 test
의 역할을 두 배로 하고 bash, zsh 및 기타 쉘에서도 사용되는 명령입니다.[
[[
C와 같은 대부분의 언어에서 절이 참 또는 거짓으로 알려지면 연산 측면에서 나머지를 계산할 필요가 없습니다. 참이면 논리가 뒤따르지 않습니다.또는거짓인 경우 논리 뒤에 따르거나 따르지 않음그리고등. 물론 이는 다음 절에서 포인터를 역참조하려고 시도하는 대신 포인터가 NULL일 때 중지할 수 있도록 허용합니다.
하지만쉿생성자 [ expr1 -o expr2 ]
(bash의 구현 포함)는 이를 수행하지 않습니다. 항상 양쪽을 평가하며 한쪽이 원하는 경우에만 평가합니다.식 1평가됩니다. 이는 test
명령 구현과의 호환성을 위해 수행될 수 있습니다. sh ||
와 &&
do는 일반적인 원칙을 따릅니다. 즉, 결과가 바뀌지 않으면 평가하지 마세요.
따라서 주목해야 할 차이점은 다음과 같습니다.
: > /tmp/effect #clear effect
if [ 1 -eq 1 -o $(echo 1; echo or-was-evaluated > /tmp/effect) -eq 1 ]; then
echo true;
fi
cat /tmp/effect
생산하다:
true
or-was-evaluated
위의 각 명령은 이전에 셸에 내장되어 사용되었던 명령 의 별칭 [
으로 대체될 수 있습니다 ./usr/bin/[
test
[
다음 두 구성은 다음과 같습니다.
: > /tmp/effect #clear effect
if [ 1 -eq 1 ] || [ $(echo 1; echo or-was-evaluated > /tmp/effect) -eq 1 ]; then
echo true;
fi
cat /tmp/effect
또는
: > /tmp/effect #clear effect
if [[ 1 -eq 1 || $(echo 1; echo or-was-evaluated > /tmp/effect) -eq 1 ]]; then
echo true;
fi
cat /tmp/effect
단지 생성 true
하고 비워 둡니다 effect
. ||
올바르게 작동하고 [[
문제도 수정합니다.
고쳐 쓰다:
@StéphaneChazelas가 댓글을 달았듯이 원래 질문과 관련된 몇 가지 차이점을 놓쳤습니다. 여기서 (적어도 나에게는) 가장 중요한 것, 즉 운영자 우선 순위를 언급하겠습니다.
쉘은 우선순위를 고려하지 않지만:
if true || true && false; then
echo true
else
echo false
fi
생성합니다( 우선순위가 없으므로 먼저 true || true
평가한 다음 && false
).
false
[[ ]]
연산자는 다음보다 내부적 &&
으로 우선 합니다 ||
.
if [[ 1 -eq 1 || 1 -eq 1 && 1 -eq 0 ]]; then
echo true
else
echo false
fi
산출량( 1 -eq 1 && 1 -eq 0
그룹화되어 있으므로 의 두 번째 구성원임 ||
):
true
적어도변화 많은,세게 때리다,다루기 힘든.
따라서 직접 쉘 논리 연산자에 비해 [[ ]]
동작이 개선되었습니다 .[ ]