我需要为 Java 应用程序伪造时间(这就是使用 --exclude-monotonic 的原因),我需要指定准确的时间戳,但我需要时钟滴答作响,而不是冻结。对于该行为 IIUC,我必须使用以下示范命令:
faketime --exclude-monotonic -f "@2030-11-02 12:47:00" bash -c 'watch -n 0.5 date';
省略--exclude-monotonic
不会产生差异。观察到的行为是watch
右上角的命令在 2030 年滴答作响(很棒!),但产生的日期date
没有滴答作响,并且卡在启动时间。我在 java 应用程序中遇到了同样的卡住行为,但提供的示例更好地演示了该问题。
这是为什么?
答案1
如果您使用尝试过的命令,时钟开始时间将应用于环境中执行的每个命令faketime
。实际上,该@
符号声明所有子进程都应从此绝对时间开始。使用高级格式时,没有简单的方法可以为所有子进程声明一个共享且自洽的起点:
faketime --exclude-monotonic -f "@2030-11-02 12:47:00" bash -c 'watch -n 0.5 date'
这里, 的时间watch
与 报告的时间不一致date
。
看看来源我注意到此行为仅在“高级时间戳规范格式”处于活动状态时才适用(即您已使用过-f
):
case '@': /* Specific time, but clock along relative to that starttime */
该+
符号声明了一个相对偏移量,但要确定相对偏移量,您必须执行日期数学并从目标开始日期中减去当前日期/时间:
offset=$(( $(date --date '2030-11-02 12:47:00' +%s) - $(date +%s) ))
faketime --exclude-monotonic -f "+$offset" bash -c 'watch -n 0.5 date'
可怕。
幸运的是,您的特定时间戳格式可以被正确解析而不需要高级格式化,这将提供您想要的行为:
faketime --exclude-monotonic "2030-11-02 12:47:00" bash -c 'watch -n 0.5 date'