正在等待在Bash中创建文件
我需要创建一个bash脚本来等待创建一个文件。脚本将在while循环中使用sleep命令,每隔10秒定期检查一个文件。等待时打印消息。创建文件后显示文件的内容。下面是我试图实现的,但显然不起作用。在这一点上,我不完全确定如何继续正在等待在Bash中创建文件,bash,unix,Bash,Unix,我需要创建一个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:"
#!/bin/bash
let file=$1
while '( -f ! /tmp/$1)'
do
sleep 10
echo "still waiting"
done
echo "Content of the file $1:"
这里的问题在于测试,而不是睡眠(正如最初的问题所假设的那样)。可能的最小修复可能如下所示:
while ! test -f "/tmp/$1"; do
sleep 10
echo "Still waiting"
done
请记住
while
循环的语法:
也就是说,当扩展循环时,给的第一个参数是命令;它需要遵循与任何其他shell命令相同的语法规则
-f
作为test
的参数是有效的,该命令也可以在[
的名称下访问,在该名称中使用时需要一个]
作为最后一个参数,但它本身作为命令无效,并且当作为字符串的一部分传递时,它甚至不是可以解析为单个命令名或参数的shell单词
当您以命令的形式运行(-f!/tmp/$1)
时,在引号内,shell将查找具有该名称的实际命令(包括空格)。您的路径中可能没有名为'/usr/bin/(-f!/tmp/$1)
的文件,或者找不到名为该文件的任何其他命令,因此它总是会失败--在循环时立即退出
顺便说一句——如果你想让你的代码操作系统具体化,除了使用sleep
等待文件存在外,还有其他方法。例如,考虑<代码> NoTyjyWalth/<代码>,从<代码> iNosiToice < /COD>包:
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”
)可防止带有空格或通配符的名称扩展为多个不同的参数
- 在
echo
上使用&2
命令记录供人使用,可使stderr可用于编程使用
let
用于数学,而不是通用作业。如果您想使用“$file”
,这没什么错——但是赋值应该是file=$1
,前面没有let
“(…)”
是一个字符串,它可以归结为,而true则是。在[!-f/tmp/$1]
或类似的时候试试。@MarcB,嗯?不而为真
;它是而不是false
,因为该字符串不是有效的命令。如果它在一个测试中,那么它可能是TUE。BTW,在未来,考虑使用<代码> BASH-X YuScript < /C>来确定执行过程中发生了什么——在这种情况下,这将表明我们正从“代码>”(-f./tMP/$ 1)“<代码> > <代码> ECHO”文件的内容1美元:“<代码>这样就排除了睡眠的问题(因为它根本没有运行)。@MarcB,…顺便说一句,它将是,而[!-f/tmp/“$1”]
——在之间的空间
和-
是必需的,同样,扩展周围的引号也是必需的(以避免字符串拆分和全局扩展产生大量不希望出现的行为)。或者while!test-f“/tmp/$1”
,或任何其他写入方式。对于Mac用户,您可以使用fswatch
而不是inotifywait
:fswatch--event Created--event Updated“$INPUT\u DIR”
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