我需要创建一个bash脚本来等待创建文件。该脚本将在while循环中使用sleep命令,每10秒定期检查一个文件。等待时打印留言。创建文件后显示文件的内容。以下是我试图实现的内容,但显然无效。在这一点上,我不完全确定如何继续。
#!/bin/bash
let file=$1
while '( -f ! /tmp/$1)'
do
sleep 10
echo "still waiting"
done
echo "Content of the file $1:"
答案 0 :(得分:12)
这里的问题是测试,而不是睡眠(正如假设的原始问题)。可能的最小修复可能如下所示:
while ! test -f "/tmp/$1"; do
sleep 10
echo "Still waiting"
done
请记住while
循环的语法:
while: while COMMANDS; do COMMANDS; done Expand and execute COMMANDS as long as the final command in the `while' COMMANDS has an exit status of zero.
也就是说,扩展循环的while
的第一个参数是命令;它需要遵循与任何其他shell命令相同的语法规则。
-f
作为test
的参数有效 - 这个命令也可以在名称[
下访问,在使用时需要]
作为最后一个参数这个名字 - 但它本身并不是一个有效的命令 - 当作为字符串的一部分传递时,它甚至不是可能的shell字解析为单独的命令名称或参数。
当您在命令内运行'( -f ! /tmp/$1)'
时,shell会查找具有该名称的实际命令(包括空格)。您可能没有在PATH中找到名为'/usr/bin/( -f ! /tmp/$1)'
的文件或找到该名称的任何其他命令,因此它总是会失败 - 立即退出while
循环。
顺便说一句 - 如果您愿意使您的代码特定于操作系统,那么除了使用sleep
等待文件存在之外,还有其他方法。例如,考虑inotifywait
包中的inotify-tools
:
while ! test -f "/tmp/$1"; do
echo "waiting for a change to the contents of /tmp" >&2
inotifywait --timeout 10 --event create /tmp >/dev/null || {
(( $? == 2 )) && continue ## inotify exit status 2 means timeout expired
echo "unable to sleep with inotifywait; doing unconditional 10-second loop" >&2
sleep 10
}
done
基于inotify的界面的好处是它会在文件系统更改时立即返回,并且不会产生轮询开销(如果它阻止系统休眠,这可能会特别重要)。
顺便说一下,一些练习笔记:
"/tmp/$1"
)可防止带有空格或通配符的名称扩展为多个不同的参数。>&2
命令上使用echo
来记录供人类消费,可以让stderr用于程序化消费let
用于数学,而不是通用作业。如果您想使用"$file"
,那么没有任何问题 - 但是分配应该是file=$1
,而不是先前let
。