我写字的地方相当有规律的一些东西写shell脚本 到文件中,之后,执行应用程序,读取该文件。我发现,通过我们公司的网络延迟的不同千差万别,因此,例如一个简单的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用户对脚本去世之前,否则什么失败)。

另一个问题是用“$测试”来保存一个命令意味着你没有得到的时候实际执行,只是评估shell扩展。所以,如果你说测试=“grep的\”福\“\‘栏巴兹\’”,而不是寻找与七个字符的名称栏巴兹该文件中的三个字母串富,它会看起来五个字符的字符串在九个字符文件 “foo” 的 “条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会的工作了。该散列是从写入器广播到(多个)读取器,并且读取器等待直到)文件大小停止增加和b)的文件的(新鲜计算的)散列由作家发送的散列相匹配。

我们也有类似的问题,但出于不同的原因。我们正在读S档,被发送到SFTP服务器。运行脚本的机器不是SFTP服务器。

我所做的是将其设置在cron(虽然睡眠循环将工作太)做文件的校验和。当旧的校验和的当前校验和相匹配(该文件并没有改变的时间所确定的量),我们知道,写入完成,并传送该文件。

只是要更加安全,我们从来没有制作备份覆盖前一个本地文件,并且只传递在所有当远程文件在匹配连续两个cksums,并校验和不匹配的本地文件。

如果您需要的代码示例,我相信我可以挖起来。

在外壳劈开你的谓词进言。抓住它所有$@如在下面的代码:

#! /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”是你的逻辑是:这将阻塞,直到发送方已经写入它的输出。从理论上讲笔者程序将不需要modifiying ....

警告:如果接收器不因某种原因运行,则最终可能会阻塞发件人

不知道它适合你的要求,在这里,但可能是值得研究的。

或避免同步,尝试 'lsof的'?

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

假设你只是想从当没有其他书面形式向它(即写作过程已经完成)读取文件 - 你可以检查是否没有其他具有文件句柄到它

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top