원격 호스트에 SSH로 접속하는 스크립트를 작성하고, 명령을 실행하고, 출력을 파일에 저장하고, 출력을 검사했습니다. 그러나 (( success++ ))
배열의 첫 번째 항목을 반복할 때 항상 자동으로 종료됩니다 workers
. (( success++ ))
로 바꾸면 echo "process $worker"
제대로 작동하고 모든 호스트를 인쇄합니다. 나는 무엇이 잘못되었는지 모른다.
#!/bin/bash
set -x
set -e
workers=('host-1' 'host-2' 'host-3')
output_dir=$(mktemp -d)
for worker in ${workers[@]}; do
ssh $worker '
echo abc
echo OK
' > "$output_dir/$worker" &
done
echo "waiting..."
sleep 3
wait
success=0
regexp='OK$'
for worker in ${workers[@]}; do
output=`cat "$output_dir/$worker"`
if [[ "$output" =~ $regexp ]]; then
(( success++ ))
fi
done
echo "Total ${#workers[@]}; success: $success; failure: $((${#workers[@]} - success))"
답변1
간단한 예를 통해 그 이유를 설명할 수 있습니다.
$ ((success++))
$ echo $?
1
왜냐하면0 값을 생성하는 모든 산술 연산1을 반환.무슨 말을 해야 할지 모르겠습니다. Bash는 세상에 충분한 함정을 가져왔습니다.
답변2
설정한 결과입니다 -e
. 종료 코드가 1(0이 아님)인 명령은 종료를 트리거합니다.
이 스크립트는 잘 작동합니다.
#!/bin/bash
(( success++))
echo "Still going 1 $success"
이것은 아니다
#!/bin/bash
set -e
(( success++))
echo "Still going 1 $success"
해결책
가장 쉬운 방법은 set -e
실을 제거하는 것입니다.
이것이 옵션이 아닌 경우 다음을 사용하십시오.
(( ++success ))
다른 대안:
#!/bin/bash
set -e
success=0
success=$(( success+1 ))
echo "still going 1 $success"
success=0
(( success=success+1 ))
echo "still going 2 $success"
success=0
(( success+=1 ))
echo "still going 3 $success"
success=0
(( ++success ))
echo "still going 4 $success"
success=0
(( success++ ))
echo "still going 5 $success"
옵션 번호 5에만 종료 코드가 1입니다.
기타(모든 변수 값에 대한 더 복잡한 솔루션 a
).
첫 번째로 사용되는 것은(POSIX) :
내장 콜론( )POSIX와 호환되게 만드세요.
: $(( a+=1 )) ; echo "6 $a $?" ## Valid Posix
(( a++ )) || true ; echo "7 $a $?"
(( a++ )) || : ; echo "8 $a $?"
(( a++ , 1 )) ; echo "9 $a $?"
(( a++ | 1 )) ; echo "10 $a $?"