题
我写字的地方相当有规律的一些东西写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
假设你只是想从当没有其他书面形式向它(即写作过程已经完成)读取文件 - 你可以检查是否没有其他具有文件句柄到它