Linux 每秒执行一个命令,同时考虑命令运行所需的时间
我有一个脚本,它以%H:%M:%S格式读取时间,将其绘制在图像上,并将该图像设置为墙纸。而且效果很好: 现在,大约每五秒钟,脚本就会跳过一秒钟。我相信这是脚本完成工作所花费的时间,大约每五秒钟就累积到一秒钟。但我不知道如何修复它 下面是设置时间的循环: 而睡眠1;不要设置时钟;完成 下面是设置时钟功能: 摆钟{ 时钟时间=$date+“%H:%M:%S” 皈依\ -大小$monitor\u分辨率\ xc:$background\u color\ -字体$clock\u字体\ -填充$clock_颜色\ -pointsize$时钟大小\ -重心\ -绘制文本0,0'$clock\u time'\ $config_dir/background.png feh-背景比例$config_dir/background.png } 我不认为这里需要所有的脚本,但是 我怎样才能解决这个问题?因此显示的时间是准确的。创建一个名为delay的变量。调用set_clock后,使用date+%N获取当前纳秒。将延迟设置为1减去当前纳秒,并将循环更改为while sleep$delay,而不是while sleep 1 这样,您的循环将只休眠到下一秒的顶部Linux 每秒执行一个命令,同时考虑命令运行所需的时间,linux,bash,Linux,Bash,我有一个脚本,它以%H:%M:%S格式读取时间,将其绘制在图像上,并将该图像设置为墙纸。而且效果很好: 现在,大约每五秒钟,脚本就会跳过一秒钟。我相信这是脚本完成工作所花费的时间,大约每五秒钟就累积到一秒钟。但我不知道如何修复它 下面是设置时间的循环: 而睡眠1;不要设置时钟;完成 下面是设置时钟功能: 摆钟{ 时钟时间=$date+“%H:%M:%S” 皈依\ -大小$monitor\u分辨率\ xc:$background\u color\ -字体$clock\u字体\ -填充$clock_
只有在图像的构建和显示时间始终少于一秒钟时,这才能解决问题。如果系统非常忙,并且您的过程需要一秒钟以上才能完成,它仍然会跳过一秒钟。您需要一种跟踪开始时间的工具,并在重复之前计算正确的睡眠时间 您可以自己编写,但使用watch和-p/-precise参数更容易:
$ watch -n 1 -p 'sleep 0.5; date +%s.%N'
即使重复的命令休眠半秒,也不会延迟下一个命令;每次的毫秒数大致相同
嗯,不过它不能与shell函数一起工作,因为watch将在子进程中执行您的命令。您必须将整个命令扩展到watch参数中,这可能会给相对较长的命令带来不便。使用主计时键,在后台运行set_clock,直到当前秒结束,如下所示: !/usr/bin/env bash 摆钟{ printf-v时钟时间''%H:%M:%ST' 皈依\ -大小$monitor\u分辨率\ xc:$background\u color\ -字体$clock\u字体\ -填充$clock_颜色\ -pointsize$时钟大小\ -重心\ -绘制“文本”0,0'$clock\u time\ $config_dir/background.png feh-背景比例$config_dir/background.png } while:;做 在后台启动时钟更新 摆钟& 睡眠到当前秒结束 睡眠。$10**9-10$date+%N 如果背景子时钟仍在运行,请将其杀死! {kill-0$!&&kill$!;}2>/dev/null 完成
你可以这样做:
while sleep $(perl -MTime::HiRes=gettimeofday -E '$n=gettimeofday; say 1-($n-int($n))'); do
...
done
while slow_cmd; do
perl -MTime::HiRes=gettimeofday,usleep -w -e '$n=gettimeofday;
usleep 1e6*(1-($n-int($n)))'
update_status # Quick cmd to report results of slow_cmd
done
请注意,您可能希望在完成需要时间的命令后进行睡眠。比如:
while sleep $(perl -MTime::HiRes=gettimeofday -E '$n=gettimeofday; say 1-($n-int($n))'); do
...
done
while slow_cmd; do
perl -MTime::HiRes=gettimeofday,usleep -w -e '$n=gettimeofday;
usleep 1e6*(1-($n-int($n)))'
update_status # Quick cmd to report results of slow_cmd
done
您可以尝试使用date来获取高分辨率计时器,但我发现perl在实践中更具可移植性,也不那么令人惊讶。另外,请注意,出于同样的原因,我以第二种形式将睡眠推入了perl。也就是说,sleep通常不接受亚秒精度,但perl的usleep接受亚秒精度。一个懒惰的解决方案是每秒只运行两次,改为使用sleep 0.5。@NateEldredge一个符合我心意的人!我们喜欢简单的解决方法:-这有什么意义?只需使用时钟小部件。或者只需在后台运行set_clock,这样它就不会计入1秒的迭代时间。@oguzismail不仅仅是时钟,我还计划在墙纸上添加更多内容。我没有使用任何桌面环境,我现在使用的是窗口管理器bspwm。我还没有发现任何像编写自己的脚本那样可以自定义的小部件。这是一个很好的解决方案,但是[-n$!]始终是正确的,因为$的值!在子对象终止时不会更改。最好使用另一种方法来测试孩子是否完成了,以避免向无意中的接收者发送信号。我真的很喜欢亚秒睡眠技巧,但仍然看不出使用信号的意义。睡觉时。。。;设置时钟并完成同样的事情,不是吗?@oguzismail是的,这里不需要使用信号^^