Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
正在等待在Bash中创建文件_Bash_Unix - Fatal编程技术网

正在等待在Bash中创建文件

正在等待在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:"

我需要创建一个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:"

这里的问题在于测试,而不是睡眠(正如最初的问题所假设的那样)。可能的最小修复可能如下所示:

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