bash에서 if 문을 반복하는 방법은 무엇입니까?

bash에서 if 문을 반복하는 방법은 무엇입니까?

사용자에게 질문을 한 다음 답변을 제공하고 i라는 변수에 저장되도록 하고, 답변(파일)이 존재하고 쓰기 가능한 경우 이를 읽고 내용을 파악합니다. 파일 및 넣기 이 내용은 새 내용에 기록됩니다. 파일이 존재하지 않거나 사용자에게 파일에 대한 충분한 권한이 없으면 경고 메시지가 표시되고 프로그램은 3초 동안 절전 모드로 전환된 후 루프를 다시 시작합니다. 왜 작동하지 않나요? 경고는 사라지지 않고 주기가 계속되지 않습니다.

echo "$(tput setaf 4)  Tell me where the file is:"
printf "\n"

a=false
while [ $a=true ]; do
    read i
    if [ -w $i ]
        then cat $i | grep stuff > i2
    else
        a=true
        printf "Oh something is wrong, try again!"
            sleep 3
    fi
done

답변1

문법적, 논리적 오류가 있습니다.

이는 $a=true비교 연산이 아닌 단순한 문자열입니다. 쉽게 비교할 수 있도록 공백으로 구분합니다. "$a" = true.

이 작업을 완료하고 나면 미리 설정해 두었으므로 루프에 전혀 들어가지 않게 됩니다 a=false.

루프에 빠지면 가 아닌 a다른 것으로 설정된 적이 없고 true다른 종료 메커니즘이 제공되지 않기 때문에(예 break: ) 종료할 수 없습니다.

답변2

다른 사람들이 지적했듯이 코드에는 논리 오류와 구문 오류가 있습니다. 이것쉘체크 웹사이트문법 오류를 해결하는 데 도움이 됩니다.

여기에 내 의견이 있습니다. 두 가지 버전의 코드가 있습니다. (내가 선호하는) 첫 번째는 사용자 상호 작용이 없지만 명령줄에서 경로 이름을 사용합니다. 두 번째는 대화식으로 경로 이름을 묻습니다.

대화식으로 경로 이름을 묻는 메시지를 표시하지 않는 첫 번째 이유는 스크립트 사용자가 명령줄이나 스크립트 프롬프트에서 경로 이름을 쓰는 경우 아무런 차이가 없고 경로 이름에 대한 스크립트 프롬프트를 사용하면 아무런 차이가 없기 때문입니다. 예를 들어 크론 작업이나 터미널이 연결되지 않은 다른 곳에서 사용할 수 있습니다.

#!/bin/sh

pathname=$1

if ! grep 'pattern' <$pathname >i2; then
    echo 'Something is wrong' >&2
fi

위의 명령문은 echo다음과 같은 경우에 실행됩니다.

  • $pathname의 파일을 읽을 수 없거나
  • 파일 i2에 쓸 수 없거나
  • 패턴을 찾을 수 없습니다 $pathname(귀하의 코드와 다르지만 아래를 참조하세요).

일반 진단 메시지를 사용자 정의하는 것처럼 오류 메시지는 표준 오류에 기록됩니다.

대화형 프롬프트 및 지연:

#!/bin/bash

while true; do
    read -r -p 'Pathname: ' pathname

    if grep 'pattern' <$pathname >i2; then
       break
    fi

    echo 'Something is wrong' >&2
    sleep 3
done

grep여기에는 사용자로부터 데이터를 읽고 호출이 정상이면 루프에서 벗어나는 무한 루프가 있습니다. 어떤 이유로(위의 세 가지 이유 중 하나) 실패 하면 grep경로 이름을 묻는 메시지가 다시 표시됩니다.


두 코드 모두 읽기 가능한 파일에 대한 별도의 테스트를 갖고 있습니다( grep아무 것도 찾을 수 없거나 출력 파일에 쓸 수 없기 때문에 실패할 수 있음).

첫째, 비대화형 버전:

#!/bin/sh

pathname=$1

if [ ! -r "$pathname" ]; then
    echo 'Something is wrong' >&2
fi

grep 'pattern' <$pathname >i2

그리고 대화형 버전이 있습니다.

#!/bin/bash

while true; do
    read -r -p 'Pathname: ' pathname

    if [ -r "$pathname" ]; then
       grep 'pattern' <$pathname >i2
       break
    fi

    echo 'Something is wrong' >&2
    sleep 3
done

또는 루프가 사용자 입력 및 유효성 검사만 처리하는 대화형 버전:

#!/bin/bash

while true; do
    read -r -p 'Pathname: ' pathname

    [ -r "$pathname" ] && break

    echo 'Something is wrong' >&2
    sleep 3
done

grep 'pattern' <$pathname >i2

답변3

다음과 같이 간단한 중단을 사용하여 무한 루프를 중지해 보세요.

echo "$(tput setaf 4)  Tell me where the file is:"
echo # This prints empty line like printf "\n"

while true; do # 'while true' or 'while :' is infinite loop
    read i
    if [ -r $i ]    # You probably mean -r (readable) and not -w (writable)
    then
        cat $i | grep stuff > i2
        break # 'break' ends loop
    else
        echo -n "Oh something is wrong, try again!" # 'echo -n' means print without newline character
        sleep 3
    fi
done

수정사항에 대한 의견과 설명이 있습니다.

관련 정보