.{}
()
아래 코드 조각에서:
#!/bin/bash
set -e
echo "two">file.txt
ARRAY=(one two three)
rc=0
for i in ${ARRAY[@]}; do
echo "grepping $i "
#grep "$i" file.txt || (echo "failed grep" && exit 1) <--1
#grep "$i" file.txt || {rc=$? && echo "failed grep"} <--2
grep "$i" file.txt || (rc=$? && echo "failed grep") <--3
done
exit $rc
명령 2는 작동하지 않는 유일한 명령입니다. 그러나 나는 그것이 작동할 것이라고 예상했고 명령 1은 허용된 답변에 따라 스크립트를 종료하지 않습니다.여기
무슨 일인지 설명해 줄 수 있는 사람이 있나요?
답변1
bash
대부분의 POSIX 셸 에서 while (
및 는 셸 구문의 특수 표시 문자입니다( , , , , ... )
와 같은 다중 문자 표시의 일부를 포함하여 발생할 때마다 특별히 처리됩니다 ) . 조합은 in과 같은 특수 표시 문자를 사용 하거나 특수 또는 양식에 사용됩니다.((
$(
<(
$((
<#((
{
}
${
{x,y}
{x..y}
echo )
while 은 오류가 발생 하지만 echo }
출력이 없으므로 in 을 닫는 것이 불가능하다는 것을 알 수 있습니다 .}
}
{echo}
{
구체적 으로 {
와}
핵심 단어좋다 while
, time
, !
. 명령이 필요한 경우에만(첫 번째 근사치에서) 별도의 단어로만 나타날 수 있습니다.
{echo
뒤에 오는 키워드 {echo
가 아니라 명령이 됩니다 . 키워드 다음에 it 이 오는 대신 명령 과 같습니다 .{
echo
while[
while[
while
[
및 가 분리되어 명령 위치에 있는 경우 또는 를 사용할 수 있지만 은 사용할 수 없습니다 { echo;}
.{<file cat;}
{
}
{echo}
그러나 몇 가지 예외가 있습니다. 일반적으로 리디렉션 외에는 아무 일도 일어나지 않고 명령 위치에 없는 {(echo test)}
닫힌 후에도 이 작업이 작동한다는 것을 알 수 있습니다 . 지휘 위치에 있지 않은 두 번째 사람 도 마찬가지입니다.)
}
{ { echo; } }
}
{ echo; ! }
또는 { echo; time }
ksh93에서는 작동하지만 작동하지 않습니다 ( 명령 위치에 bash
있더라도 ).}
한 가지 예외는 가능한 경우 및 를 토큰으로 인식 zsh
하려고 시도하는 것 입니다 . 즉, 지휘 위치에 있고 특정 제한된 상황에 있을 때입니다. 거기에서는 작동하지만 예를 들어 작동하지는 않습니다 . bash/ksh 대신 거기 처럼요 .{
}
{echo}
{{echo}}
{{echo} }
{echo,foo}
{ echo,foo;}
echo foo
<file {head;head}
작동 zsh
하지만 다른 쉘에서는 작동하지 않습니다.
이는 IGNORE_BRACES
및 옵션에 의해 IGNORE_CLOSE_BRACES
제어 됩니다.
답변2
콜론 으로 {}
구분된 형식 복합 명령문의 자리 표시자 이며 변수 업데이트가 중괄호 외부에 반영되지 않는 하위 쉘 컨텍스트를 만듭니다.bash
()
$?
grep
또는 다른 쉘 명령을 사용할 때 반환 코드 값을 망칠 필요조차 없습니다. 0
콘솔 출력을 억제하여 if 조건에서 직접 종료 코드를 사용할 수 있습니다 (일반적으로 성공하면 명령을 반환함). 플래그를 grep
활성화하면 -q
이 작업을 수행 할 수 있습니다.
if grep -q "$i" file.txt; then
printf "grep suceeded\n"
else
printf "grep failed\n"
fi
종료 코드를 수동으로 저장하려면 복합 문을 사용하는 것이 맞습니다(여기서는 서브쉘 사용이 작동하지 않습니다!). 복합문을 다음과 같이 끝내면 됩니다.;
grep "$i" file.txt || {rc=$? ; echo "failed grep" ; }
이제 종료 코드를 사용할 수 있습니다 rc
. 또는 더 간단하게는 echo 자체에서 변수를 사용할 수 있습니다.
grep "$i" file.txt || echo "failed grep with rc: $?"
sub-shell을 사용하여 답변에 추가하려면 ()
변수 컨텍스트를 저장하는 것이 좋습니다.아니요좋은 습관입니다. 연결된 명령이 완료된 직후 셸이 종료됩니다.
예를 들어 다음과 같은 간단한 문자열 동일성 연산을 사용하세요.
str='foo'; rc=0
[[ $str == *doo* ]] || { rc=$?; echo "string comparison failed" ; }
echo "$rc"
값을 올바르게 반영 rc
하지만 서브쉘의 경우 작동하지 않습니다.
str='foo'; rc=0
[[ $str == *doo* ]] || ( rc=$?; echo "string comparison failed" )
echo "$rc"
서브쉘 내에서 0
설정할 때 반환되어야 하는 값을 반영합니다.1
[실제 문제와 관련 없음]
항상 배열 확장을 인용해야 합니다. 그렇게 하지 않으면 공백이나 기타 특수 문자가 포함된 배열 요소를 하나의 단어로 처리하지 않고 별도의 단어로 분할합니다.
for i in "${ARRAY[@]}"; do