문제

쓰 쉘 스크립트는 매우 정기적으로 어떤 물건을 기록 파일,그 후 응용 프로그램이 실행되는 읽는 파일입니다.내가 찾는 것을 통해 우리의 회사는 네트워크는 대기 시간을 크게 다릅므로,단순한 sleep 2 예를 들어이 되지 않을만큼 강력.

나도(구성)시간 제한 루프 다음과 같다:

waitLoop()
{
   local timeout=$1
   local test="$2"

   if ! $test
   then
      local counter=0
      while ! $test && [ $counter -lt $timeout ]
      do
         sleep 1
         ((counter++))
      done

      if ! $test
      then
         exit 1
      fi
   fi
}

이 작품에 대한 test="[ -e $somefilename ]".그러나,테스트 존재를 충분하지 않습니다,나는 때로는지 여부를 테스트해야는 특정 문자열에 기록되었는 파일입니다.나 test="grep -sq \"^sometext$\" $somefilename", 지만,이 작동하지 않았습니다.할 수 있는 누군가가 나에게 왜?

다른,더 적은 자세한 옵션을 수행할 수은 이러한 테스트?

도움이 되었습니까?

해결책

이 방법으로 테스트 변수를 설정할 수 있습니다.

test=$(grep -sq "^sometext$" $somefilename)

당신의 이유 grep 작동하지 않는 것은 인용문이 실제로 논쟁에서 통과하기가 어렵다는 것입니다. 사용해야합니다 eval:

if ! eval $test

다른 팁

말하고 싶습니다 그만큼 텍스트 파일에서 문자열을 확인하는 방법은 grep입니다.

정확한 문제는 무엇입니까?

또한 루트 문제를 제거하기 위해 NFS 마운트 매개 변수를 조정할 수 있습니다. 동기화도 도움이 될 수 있습니다. NFS 문서를 참조하십시오.

만약 당신이 사용하고자하는 waitLoop 에서"if",을 변경할 수 있습니다"출구"를"return",나머지 스크립트 오류를 처리할 수 있는 상황(거의 심지어 사용자에게 메시지에 대해 무엇을 못하기 전에 스크립트가 죽으면 그렇지 않으면).

다른 문제는 사용하는"$테스트"를 개최하는 명령어 당신을 의미하지 않을 얻을 쉘 확장을 할 때 실제로 실행하고,그냥 검토하는 것이 좋습니다.그래서 만약 당신이 말하 테스트="grep\"foo\"\"바 baz\"",보를 위해 세 개의 문자열 푸에서 파일이븐 캐릭터 이름을 바 baz,그것을 찾기 위해 오 char 문자열"foo"에서 구 char 파일에"바 baz".

할 수 있도록 하나로 결정을 할 필요가 없는 셸 마법,그리고 설정한 테스트='grep-sq^sometext$somefilename',또는 당신을 얻을 수 있는 쉘을 처리할을 인용하여 명시적으로 다음과 같습니다.

if /bin/sh -c "$test"
then
   ...

파일 수정 시간을 사용하여 파일 수정 시간을 열지 않고 작성된 시점을 감지하십시오. 같은 것

old_mtime=`stat --format="%Z" file`
# Write to file.
new_mtime=$old_mtime
while [[ "$old_mtime" -eq "$new_mtime" ]]; do 
  sleep 2;
  new_mtime=`stat --format="%Z" file`
done

그러나 여러 프로세스가 파일에 동시에 액세스하려고 시도하는 경우에는 작동하지 않습니다.

나는 똑같은 문제가있었습니다. 나는 당신이 당신의 OP에 포함시키는 타임 아웃 대기와 비슷한 접근법을 사용했습니다. 그러나 파일 크기 수표도 포함되었습니다. 마지막으로 확인 된 이후 파일 크기가 증가한 경우 타임 아웃 타이머를 재설정합니다. 내가 쓰고있는 파일은 몇 공연이 될 수 있으므로 NFS에 걸쳐 글을 쓰는 데 시간이 걸립니다.

이것은 당신의 특정 사례에 대해 과잉 일 수 있지만, 글쓰기가 완료된 후 파일의 해시를 계산했습니다. 나는 MD5를 사용했지만 CRC32와 같은 것도 효과가있을 것입니다. 이 해시는 작가에서 (다중) 독자에게 방송되었으며, 독자는 a) 파일 크기가 증가하고 b) 파일의 (신선한 계산) 해시가 작가가 보낸 해시와 일치 할 때까지 기다립니다.

우리는 비슷한 문제가 있지만 다른 이유가 있습니다. SFTP 서버로 전송되는 S 파일을 읽고 있습니다. 스크립트를 실행하는 컴퓨터는 SFTP 서버가 아닙니다.

내가 한 일은 파일의 cksum을 수행하기 위해 CRON (수면이있는 루프도 효과가 있지만)으로 설정하는 것입니다. 이전 CKSUM이 현재 CKSUM과 일치하면 (파일이 결정된 시간 동안 변경되지 않았다) 쓰기가 완료되었음을 알고 파일을 전송합니다.

추가 안전을 위해, 우리는 백업을하기 전에 로컬 파일을 덮어 쓰지 않으며, 원격 파일에 일치하는 2 개의 cksum이있는 경우에만 전송하고 CKSUM이 로컬 파일과 일치하지 않는 경우에만 전송합니다.

코드 예제가 필요한 경우 파헤칠 수 있다고 확신합니다.

껍질은 술어를 말로 나누었습니다. 모두 잡아라 $@ 아래 코드에서와 같이 :

#! /bin/bash

waitFor()
{
  local tries=$1
  shift
  local predicate="$@"

  while [ $tries -ge 1 ]; do
    (( tries-- ))

    if $predicate >/dev/null 2>&1; then
      return
    else
      [ $tries -gt 0 ] && sleep 1
    fi
  done

  exit 1
}

pred='[ -e /etc/passwd ]'
waitFor 5 $pred
echo "$pred satisfied"

rm -f /tmp/baz
(sleep 2; echo blahblah >>/tmp/baz) &
(sleep 4; echo hasfoo   >>/tmp/baz) &

pred='grep ^hasfoo /tmp/baz'
waitFor 5 $pred
echo "$pred satisfied"

산출:

$ ./waitngo 
[ -e /etc/passwd ] satisfied
grep ^hasfoo /tmp/baz satisfied

너무 나쁘다. 타입 스크립트는 실시간으로 시청하는 것만 큼 흥미롭지 않다.

좋아 ... 이건 좀 더 멍청 해요 ...

파일을 제어 할 수있는 경우 : 여기에서 '명명 된 파이프'를 만들 수 있습니다. 따라서 (작문 프로그램의 작동 방식에 따라) 파일을 동기화 된 방식으로 모니터링 할 수 있습니다.

가장 간단하게 :

명명 된 파이프 생성 :

mkfifo file.txt

동기화 수신기 설정 :

while :
do
    process.sh < file.txt
end

테스트 발신자 생성 :

echo "Hello There" > file.txt

'process.sh'는 논리가가는 곳입니다. 발신자가 출력을 작성할 때까지 차단됩니다. 이론적으로 작가 프로그램은 수정이 필요하지 않습니다 ....

경고 : 수신기가 어떤 이유로 실행되지 않으면 발신자를 차단하게 될 수 있습니다!

여기서 요구 사항에 맞지 않지만 조사 할 가치가있을 수 있습니다.

또는 동기화를 피하려면 'lsof'를 시도해보십시오.

http://en.wikipedia.org/wiki/lsof

다른 것이 없을 때 파일에서만 읽고 싶다고 가정하면 (예 : 글쓰기 프로세스가 완료되었습니다) - 다른 파일 핸들이 없는지 확인할 수 있습니까?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top