사용하려는 쉘 스크립트에서 계속 이 오류가 발생합니다.
$ ./script.sh: line 2: [: missing `]'
grep: ]: No such file or directory
이 줄은 특정 프로세스가 파일을 잠그는지 확인하는 섹션의 일부입니다.
COUNTER=0
while [ ps aux | grep "[r]elayevent.sh" ] && [ "$COUNTER" -lt 10 ]; do
sleep 3
let COUNTER+=1
done
분명히 나는 대괄호가 모두 올바르게 쌍을 이루고 있는지 확인했습니다. 이것은 나에게 괜찮아 보입니다. 또한 조건부 질문 주위의 일반적인 공백은 적용되지 않습니다.
내가 여기서 무엇을 놓치고 있는 걸까요?
답변1
에러는 [
종료 상태를 확인한 후 명령어를 직접 사용하고 싶기 때문에 먼저 삭제해야 한다는 점입니다.
위키 페이지주택 검사 도구이에 대한 설명이 있습니다 (문제 SC1014):
[ .. ]
if
명령문과 같은 쉘 구문의 일부가 아닙니다 . C와 유사한 언어에서 괄호와 동일하지 않으며if (foo) { bar; }
테스트할 명령을 묶어서는 안 됩니다.
[
whoami
or 와 같은 일반적인 명령grep
이지만 재미있는 이름이 있습니다(참조ls -l /bin/[
). 의 약자입니다test
.명령의 종료 상태를 확인하려면 해당 명령을 직접 사용하십시오.
명령의 출력을 확인하려면 문자열 비교를 위해 또는 /를
"$(..)"
사용하여 출력을 가져옵니다.test
[
[[
또한 ps aux | grep -q "[r]elayevent.sh"
이것을 사용하면 stdout
.
pgrep
또는 해당 출력을 사용하여 /dev/null
.
마지막 경우에 더 효율적이므로 두 번째 조건을 먼저 사용하십시오.
따라서 최종 스크립트는 다음과 같습니다.
#!/bin/bash
COUNTER=0
while [ "$COUNTER" -lt 10 ] && ps aux | grep -q "[r]elayevent.sh" ; do
sleep 3
let COUNTER+=1
done
또는
#!/bin/bash
COUNTER=0
while [ "$COUNTER" -lt 10 ] && pgrep "[r]elayevent.sh" >/dev/null ; do
sleep 3
let COUNTER+=1
done
답변2
그 안에 튜브가 있을 수 없습니다 [ ... ]
. pgrep
다음 출력을 구문 분석하는 것보다 사용하는 것이 더 좋습니다 ps
.
count=0
while [ "$count" -lt 10 ] && pgrep relayevent.sh >/dev/null; then
sleep 3
count=$(( count + 1 ))
done
BSD 시스템이 일반과 마찬가지로 폐기하는 pgrep -q ...
대신 사용할 수 있는 실제 출력입니다 (종료 상태에만 관심이 있습니다).pgrep ... >/dev/null
pgrep
grep
pgrep
명령을 에 넣지 않은 이유 [ ... ]
는 출력에는 관심이 없고 종료 상태에만 관심이 있기 때문입니다. [ ... ]
일반적으로 문자열이나 숫자를 비교합니다 . 이는 [ ... ]
실행과 마찬가지로 종료 상태가 0(true) 또는 0이 아닌(false)이 됩니다 pgrep
.
그러나 이는 잠금 메커니즘을 확인하지 않고 특정 프로세스가 실행 중인지 여부만 확인합니다.
스크립트의 단일 인스턴스만 실행하려는 경우 다음을 수행하는 것이 더 좋습니다( EXIT
스크립트가 순서대로 종료될 때마다 트랩이 실행된다고 가정).
lockdir=dir.lock
if mkdir "$lockdir"; then
trap 'rmdir "$lockdir"' EXIT
else
echo 'Only one instance of this script allowed' >&2
exit 1
fi
여러 번 시도한 후 잠을 잔 후:
lockdir=dir.lock
count=0
while [ "$count" -lt 10 ]; then
if mkdir "$lockdir"; then
trap 'rmdir "$lockdir"' EXIT
break
else
echo 'Locked. Sleeping...' >&2
sleep 3
fi
count=$(( count + 1 ))
done
if [ "$count" -eq 10 ]; then
echo 'Giving up.' >&2
exit 1
fi
관련된: