无限重复 bash 命令,但仅当前一个 bash 命令完成时
repeat bash command infinitely, but only when the previous bash command has finished
在我们用于构建的 macOs 虚拟机上,有时会无缘无故地跳出时间。作为解决方法,我创建了这个名为 test.sh
的脚本,它始终纠正时间:
#!/bin/bash -e
while true; do
sudo ntpdate -u de.pool.ntp.org >> ntpdate.txt; sleep 30;
done
在构建开始时,它会在后台启动:
./test.sh &
构建完成后,我将终止它:
kill $(ps aux | grep test.sh | grep -v grep | awk '{print }')
有时更新时间的调用需要超过 30 秒。然后有两个对 ntp 池的公开调用,我收到了速率限制响应。因此,我想将对 ntp 的调用一次限制为一次。我如何在我的 while true 循环中实现这一点?
在Bash中实现互斥的一个简单方法是使用"lockfile."检查文件是否存在,如果存在,则不进行NTP查询。如果该文件不存在,则创建它。在发生崩溃的情况下,一个有用的增强功能是检查文件时间是否超过几分钟,在这种情况下可以将其删除。
您能否尝试查看以下是否适用于您的情况。
#!/bin/bash
while true; do
pid=0
sudo ntpdate -u de.pool.ntp.org >> ntpdate.txt & pid=(${!})
wait $pid
done
感谢所有建议。正如 Charles Duffy 提到的那样,我的代码只有在上一个命令完成时才会继续执行。我测试过它:
#!/bin/bash -e
while true; do
echo "start ntpdate"
sudo ntpdate -u de.pool.ntp.org >> ntpdate.txt;
echo "going to sleep"
sleep 30;
done
显然,睡眠计时器太低,无法 运行 进入速率限制响应。也许我得把睡眠时间调长。
正如 chepner 所建议的,我创建了一个 LaunchAgent 来处理这个问题:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>workaroundAgainstJumpingTime</string>
<key>ProgramArguments</key>
<array>
<string>sudo</string>
<string>ntpdate</string>
<string>-u</string>
<string>de.pool.ntp.org</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>/tmp/workaroundAgainstJumpingTime.stderr</string>
<key>StandardOutPath</key>
<string>/tmp/workaroundAgainstJumpingTime.stdout</string>
<key>StartInterval</key>
<integer>30</integer>
</dict>
</plist>
Charles Duffy,如果您根据您的评论做出回答"Your code already does proceed only when the previous command finished.",我会将其标记为已接受的答案。
在我们用于构建的 macOs 虚拟机上,有时会无缘无故地跳出时间。作为解决方法,我创建了这个名为 test.sh
的脚本,它始终纠正时间:
#!/bin/bash -e
while true; do
sudo ntpdate -u de.pool.ntp.org >> ntpdate.txt; sleep 30;
done
在构建开始时,它会在后台启动:
./test.sh &
构建完成后,我将终止它:
kill $(ps aux | grep test.sh | grep -v grep | awk '{print }')
有时更新时间的调用需要超过 30 秒。然后有两个对 ntp 池的公开调用,我收到了速率限制响应。因此,我想将对 ntp 的调用一次限制为一次。我如何在我的 while true 循环中实现这一点?
在Bash中实现互斥的一个简单方法是使用"lockfile."检查文件是否存在,如果存在,则不进行NTP查询。如果该文件不存在,则创建它。在发生崩溃的情况下,一个有用的增强功能是检查文件时间是否超过几分钟,在这种情况下可以将其删除。
您能否尝试查看以下是否适用于您的情况。
#!/bin/bash
while true; do
pid=0
sudo ntpdate -u de.pool.ntp.org >> ntpdate.txt & pid=(${!})
wait $pid
done
感谢所有建议。正如 Charles Duffy 提到的那样,我的代码只有在上一个命令完成时才会继续执行。我测试过它:
#!/bin/bash -e
while true; do
echo "start ntpdate"
sudo ntpdate -u de.pool.ntp.org >> ntpdate.txt;
echo "going to sleep"
sleep 30;
done
显然,睡眠计时器太低,无法 运行 进入速率限制响应。也许我得把睡眠时间调长。
正如 chepner 所建议的,我创建了一个 LaunchAgent 来处理这个问题:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>workaroundAgainstJumpingTime</string>
<key>ProgramArguments</key>
<array>
<string>sudo</string>
<string>ntpdate</string>
<string>-u</string>
<string>de.pool.ntp.org</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>/tmp/workaroundAgainstJumpingTime.stderr</string>
<key>StandardOutPath</key>
<string>/tmp/workaroundAgainstJumpingTime.stdout</string>
<key>StartInterval</key>
<integer>30</integer>
</dict>
</plist>
Charles Duffy,如果您根据您的评论做出回答"Your code already does proceed only when the previous command finished.",我会将其标记为已接受的答案。