파일이 bash에 있는지 테스트하는 While 루프


97

txt 파일이있는 경우에만 특정 변경을 수행하는 셸 스크립트를 작업 중이지만이 테스트 루프가 작동하지 않습니다. 이유가 궁금합니다. 감사합니다!

while [ ! -f /tmp/list.txt ] ;
do
      sleep 2
done

3
놀랐다고 말할 수 없습니다. 그 루프는 아무것도 변경하지 않습니다.
Ignacio Vazquez-Abrams

세미콜론은 중복됩니다. 어떤 방식으로 테스트 루프가 작동하지 않습니까? /tmp/list.txt 파일이 존재할 때까지 2 초 동안 반복적으로 휴면합니다.
Jonathan Leffler

5
나를 위해 작동합니다-파일이 스크립트 외부에서 생성되면 루프가 종료됩니다.

1
사실,이 루프는 파일이있을 때까지만 기다립니다. 나머지 스크립트는 변경을 수행합니다 ... : p
Zenet

1
그러면 while 루프가 작동합니다. 나만 ... 죄송합니다.
Zenet 2010 년

답변:


149

"작동 안함"이라고 말하면 작동하지 않는지 어떻게 알 수 있습니까?

다음을 추가하여 파일이 실제로 존재하는지 알아낼 수 있습니다.

while [ ! -f /tmp/list.txt ]
do
  sleep 2 # or less like 0.2
done
ls -l /tmp/list.txt

'echo $ SHELL'을 입력하여 Bash (또는 관련) 셸을 사용하고 있는지 확인할 수도 있습니다. 나는 CSH와 TCSH가이 루프에 대해 약간 다른 의미를 사용한다고 생각합니다.


반전 된 파일 검사를 사용하는 이유는 무엇입니까? 대신 [-f /tmp/list.txt]를 사용하면 안됩니까?
valentt 2014 년

2
@valentt no hew loop 말 그대로 "파일이 존재하지 않는 동안 잠을 자라".. 'NOT'를 제거하면 루프가 즉시 중단됩니다
Kenyakorn Ketsombut

2
한 줄 :while [ ! -f /tmp/list.txt ]; do sleep 2; done; ls -l /tmp/list.txt
DrumM

55

Linux를 사용 중이고 inotify-tools가 설치된 경우 다음을 수행 할 수 있습니다.

file=/tmp/list.txt
while [ ! -f "$file" ]
do
    inotifywait -qqt 2 -e create -e moved_to "$(dirname $file)"
done

이렇게하면 "x"초마다 폴링하는 동안 절전으로 인한 지연이 줄어 듭니다. 필요한 것으로 예상되는 경우 더 많은 이벤트를 추가 할 수 있습니다.


4
효율성을 위해 +1. 수면으로 풀링하는 것은 추합니다. inotifywait를 모르는 사람들을 위해 inotify-tools 패키지에 있습니다.
Michał Šrajer 2011 년

7
그것은 매우 편리한 도구입니다. 루프가 왜 발생하는지 궁금해하는 사람은 생성과 대기 사이의 가능한 경합 조건을 처리하고 inotifywait는 --exclude파일 이름을 필터링해야하지만 파일 이름을 제외한--include 모든 것을 무시 해서는 안됩니다 . 위의 명령은 -qq대신 인수를 사용해야합니다 >&/dev/null.
Craig Ringer 2013 년

t는 --timeout확인 빈도가 아니라입니까? inotifywait의 요점은 폴링이 없다는 것입니다
Alex Dean

1
@AlexDean 시간 제한은 경쟁 조건을 방지하는 것입니다. 수면 중에 루프가 종료되지 않기 때문에 수면을 사용한 폴링은 느리지 만 inotifywait는 이벤트를 발견하면 시간 초과 전에 종료됩니다.
yingted

1
@AlexDean 예, 그러나 TOCTTOU 경합 상태를 방지해야합니다. 그렇지 않으면 inotifywait이벤트 수신을 시작하기 직전에 파일이 생성되면 무기한 중단 될 수 있습니다.
yingted apr

4

나는 같은 문제가 있었다,! 대괄호 외부;

while ! [ -f /tmp/list.txt ];
do
    echo "#"
    sleep 1
done

또한 루프 내부에 에코를 추가하면 루프에 들어가는 지 여부를 알려줍니다.


2

비슷한 문제가 발생하여 여기로 이어 져서 동일한 경험을하는 모든 사람에게 내 솔루션을 남겨두고 싶었습니다.

내가 실행 cat /tmp/list.txt하면 파일에 즉시 배치되는 내용이 있음을 확신하더라도 파일이 비어 있음을 알았습니다 . 예상대로 작동 sleep 1;하기 직전에 넣으면 나타납니다 cat /tmp/list.txt. 파일이 생성 된 시간과 작성된 시간 사이에 지연이 있었을 것입니다.

내 최종 코드 :

while [ ! -f /tmp/list.txt ];
do
    sleep 1;
done;
sleep 1;
cat /tmp/list.txt;

이것이 누군가를 좌절시키는 30 분을 구하는 데 도움이되기를 바랍니다!


1

@ zane-hooper처럼 NFS에서 비슷한 문제가 발생했습니다. 병렬 / 분산 파일 시스템에서는 한 시스템에서 파일을 만드는 것과 파일을 "보는"다른 시스템 사이의 지연이 매우 클 수 있으므로 파일 생성 후 while 루프가 종료되기 전에 최대 1 분까지 기다릴 수 있습니다. 또한 이미 삭제 된 파일을 "보는"후유증이 있습니다.)

이것은 스크립트가 "작동하지 않는다"는 착각을 불러 일으키지 만 실제로는 공을 떨어 뜨리는 파일 시스템입니다.

알아내는 데 시간이 좀 걸렸고 누군가 시간을 절약하기를 바랍니다.

추신 이것은 또한 "부실 파일 처리기"오류의 성가신 수를 일으 킵니다.


0

bash 및 sh 모두에서 작동합니다.

touch /tmp/testfile
sleep 10 && rm /tmp/testfile &
until ! [ -f /tmp/testfile ]
do
   echo "testfile still exist..."
   sleep 1
done
echo "now testfile is deleted.."

0

다음은 시간 제한 이있는 버전 이므로 일정 시간 이 지나면 루프가 오류와 함께 종료됩니다.

# After 60 seconds the loop will exit
timeout=60

while [ ! -f /tmp/list.txt ];
do
  # When the timeout is equal to zero, show an error and leave the loop.
  if [ "$timeout" == 0 ]; then
    echo "ERROR: Timeout while waiting for the file /tmp/list.txt."
    exit 1
  fi

  sleep 1

  # Decrease the timeout of one
  ((timeout--))
done

-3

이렇게 해

while true
do
  [ -f /tmp/list.txt ] && break
  sleep 2
done
ls -l /tmp/list.txt
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.