Mo *_*inz 29 shell-script files
我正在尝试编写一个 shell 脚本,该脚本将等待文件出现在/tmp
调用的目录中sleep.txt
,一旦找到该程序将停止,否则我希望程序处于睡眠(挂起)状态,直到找到该文件. 现在,我假设我将使用测试命令。所以,像
(if [ -f "/tmp/sleep.txt" ];
then stop
else sleep.)
Run Code Online (Sandbox Code Playgroud)
我是编写 shell 脚本的新手,非常感谢任何帮助!
max*_*zig 40
在 Linux 下,您可以使用inotify内核子系统来高效地等待目录中的文件出现:
while read i; do if [ "$i" = sleep.txt ]; then break; fi; done \
< <(inotifywait -e create,open --format '%f' --quiet /tmp --monitor)
# script execution continues ...
Run Code Online (Sandbox Code Playgroud)
(假设 Bash 用于<()
输出重定向语法)
与固定时间间隔轮询相比,这种方法的优点是
while [ ! -f /tmp/sleep.txt ]; do sleep 1; done
# script execution continues ...
Run Code Online (Sandbox Code Playgroud)
是内核睡得更多。使用 inotify 事件规范,例如create,open
脚本只是在/tmp
创建或打开文件时安排执行。使用固定时间间隔轮询,您会为每个时间增量浪费 CPU 周期。
当文件已经存在时,我还包含了open
注册事件touch /tmp/sleep.txt
。
jim*_*mij 17
只需将您的测试放入while
循环中:
while [ ! -f /tmp/sleep.txt ]; do sleep 1; done
# next command
Run Code Online (Sandbox Code Playgroud)
Sté*_*las 10
inotifywait
到目前为止给出的一些基于 - 的方法存在一些问题:
sleep.txt
首先作为临时名称创建然后重命名为sleep.txt
. moved_to
除了匹配事件之外,还需要匹配事件create
sleep.txt
是否已创建。例如,如果foo\nsleep.txt\nbar
已经创建了一个文件怎么办?inotifywait
的怎么办?然后inotifywait
将永远等待已经存在的文件。安装手表后,您需要确保该文件不存在。inotifywait
在找到文件后保持运行(至少在创建另一个文件之前)。要解决这些问题,您可以执行以下操作:
sh -c 'echo "$$" &&
LC_ALL=C exec inotifywait -me create,moved_to --format=/%f/ . 2>&1' | {
IFS= read pid &&
while IFS= read -r line && [ "$line" != "Watches established." ]; do
: wait for watches to be established
done
[ -e sleep.txt ] || [ -L sleep.txt ] || grep -qxF /sleep.txt/ && kill "$pid"
}
Run Code Online (Sandbox Code Playgroud)
请注意,我们正在监视sleep.txt
当前目录中的创建,.
(因此您将cd /tmp || exit
在示例中执行 a before )。当前目录永远不会改变,所以当该管道成功返回时,它是sleep.txt
在当前目录中创建的。
当然,你可以.
用/tmp
上面的替换,但是在inotifywait
运行时,/tmp
可以重命名多次(不太可能/tmp
,但在一般情况下需要考虑)或安装在其上的新文件系统,因此当管道返回时,它可能不会是一个/tmp/sleep.txt
已经创建的而是一个/new-name-for-the-original-tmp/sleep.txt
。/tmp
也可能在间隔中创建了一个新目录,并且不会监视该目录,因此sleep.txt
不会检测到在那里创建的目录。