programing

bash에 파일이 있는지 테스트하기 위해 루프하는 동안

padding 2023. 4. 18. 21:49
반응형

bash에 파일이 있는지 테스트하기 위해 루프하는 동안

txt 파일이 존재하는 경우에만 특정 변경을 실행하는 셸 스크립트를 만들고 있는데, 이 테스트 루프가 작동하지 않습니다. 왜일까요?감사해요!

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

"Don't work" 라고 하면, 어떻게 그것이 동작하지 않는지를 알 수 있습니까?

다음과 같이 추가하여 파일이 실제로 존재하는지 여부를 확인할 수 있습니다.

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

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

Linux 상에 inotify-tools가 설치되어 있는 경우 다음을 수행할 수 있습니다.

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

이것에 의해, 「x」초마다 폴링을 실시하면서, sleep에 의해서 발생하는 지연이 감소합니다.이벤트가 필요할 것으로 예상되는 경우 이벤트를 추가할 수 있습니다.

저도 같은 문제가 있어서! 괄호 밖에 붙입니다.

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

또, 루프내에 에코를 추가하면, 루프에 들어가 있는지 아닌지가 표시됩니다.

저도 비슷한 문제에 부딪혀서 여기까지 오게 되었기 때문에 같은 경험을 하는 모든 사람에게 해결책을 남겨두고 싶었습니다.

내가 만약 도망친다면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분을 절약하는 데 도움이 되기를 바랍니다!

@zane-hooper와 마찬가지로 NFS에서도 비슷한 문제가 발생했습니다.병렬/분산 파일 시스템에서는 한 머신에서 파일을 작성하는 것과 다른 머신에서 파일을 "확인"하는 것의 지연이 매우 클 수 있습니다.따라서 파일 작성 후 최대 1분 동안 기다렸다가 루프가 종료될 수 있습니다(또한 이미 삭제된 파일이 "확인"되는 경우도 있습니다).

이것에 의해, 스크립트가 「동작하지 않는다라고 하는 착각을 일으키게 됩니다만, 실제로는, 공을 떨어뜨리고 있는 것은 파일 시스템입니다.

이걸 알아내는 데 시간이 좀 걸렸어요. 누군가 시간을 절약해 주길 바래요.

PS 이로 인해 "Stale file handler" 에러도 발생합니다.

는 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.."

루프가 에러와 함께 종료되도록 타임아웃이 설정된 버전을 다음에 나타냅니다.

# 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

그것은 이렇게 하세요.

while true
do
  [ -f /tmp/list.txt ] && break
  sleep 2
done
ls -l /tmp/list.txt

언급URL : https://stackoverflow.com/questions/2379829/while-loop-to-test-if-a-file-exists-in-bash

반응형