쉘 스크립트 while 루프: 파이프 주위에 ["]"가 누락되었습니다.

쉘 스크립트 while 루프: 파이프 주위에 ["]"가 누락되었습니다.

사용하려는 쉘 스크립트에서 계속 이 오류가 발생합니다.

$ ./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; }테스트할 명령을 묶어서는 안 됩니다.

[whoamior 와 같은 일반적인 명령 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/nullpgrepgrep

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

관련된:

관련 정보