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 

답변

구문 및 논리적 오류가 있습니다.

$a=true는 비교 연산이 아닌 문자열입니다. "$a" = true와 같이 비교가 이루어 지도록 공백으로 구분합니다.

이 작업을 수행하면

사전에.

드디어 루프에 들어가면 종료 할 수 없습니다. a는 절대 불가능합니다. true 이외의 것으로 설정되거나 다른 이탈 메커니즘 (예 : break)도 제공되지 않습니다.

답변

다른 사람들이 지적했듯이 코드에 논리적 오류와 구문 오류가 있습니다. ShellCheck 사이트 는 구문 오류를 제거하는 데 유용합니다.

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

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

#!/bin/sh pathname=$1 if ! grep "pattern" <$pathname >i2; then echo "Something is wrong" >&2 fi 

위의 echo

  • $pathname의 파일을 읽을 수 없거나
  • 에 쓸 수 없습니다. 또는
  • $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 

Answer

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

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 

수정 된 장소에 설명이있는 댓글이 있습니다.

댓글

  • grep <$i >i2 대신 cat. 또한 테스트에서와 같이 필요한 경우 변수 확장을 인용합니다. .

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다