例如,
# clock-pause
# touch a
# touch b
# convert -draw `date` text_draw.gif
# clock-resume
或者简单地
# freeze-exec sh -c 'touch a; touch b; convert -draw `date` text_draw.gif'
a
预期结果是和的时间戳b
以及绘制到图像上的文本完全相同。
是否可以?
答案1
在 Linux 上,可以编写一个覆盖time()
、gettimeofday()
和clock_gettime()
使用静态值的共享库,并将该库添加到$LD_PRELOAD
,这会欺骗许多程序。
更新:有人将其实现为datefudge
。
答案2
由于我必须实施@grawity 的解决方案,所以我认为在这里分享它会很好:
#define _GNU_SOURCE
#include <sys/types.h>
#include <dlfcn.h>
#include <stddef.h>
/* Frozen time (usual time_t, from UNIX epoch) */
const time_t fixedTime=652789800;
/* Deprecated, thus it seems not to be present in sys/types.h */
struct timezone
{
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of DST correction */
};
/* Typedef for the function ptr to the original gettimeofday */
typedef int (*gettimeofday_t)(struct timeval *tv, struct timezone *tz);
/* original gettimeofday */
gettimeofday_t gettimeofday_orig = NULL;
time_t time(time_t * t)
{
if(t!=NULL)
*t=fixedTime;
return fixedTime;
}
int gettimeofday(struct timeval *tv, struct timezone *tz)
{
if(tz!=NULL)
{
/* forward requests about tz to the original gettimeofday */
if(gettimeofday_orig==NULL)
{
gettimeofday_orig=(gettimeofday_t) dlsym(RTLD_NEXT, "gettimeofday");
if(gettimeofday_orig==NULL)
return -1;
}
int ret=gettimeofday_orig(NULL, tz);
if(!ret)
return ret;
}
if(tv!=NULL)
{
tv->tv_sec=fixedTime;
tv->tv_usec=0;
}
return 0;
}
int clock_gettime(clockid_t clk_id, struct timespec *tp)
{
(void)clk_id;
if(tp!=NULL)
{
tp->tv_sec=fixedTime;
tp->tv_nsec=0;
}
return 0;
}
测试:
matteo@teoxubuntu:~/cpp/detourtest$ gcc -O3 -fPIC -Wall -Wextra -shared timedetour.c -o libtimedetour.so
matteo@teoxubuntu:~/cpp/detourtest$ LD_PRELOAD=/home/matteo/cpp/detourtest/libtimedetour.so date
sab 8 set 1990, 12.30.00, CEST
答案3
你不能停止系统时钟。但是,您可以这样做:
now=$(date +%s.%N)
# $now now contains a Unix timestamp at nanosecond precision
touch -d @$now a b c
convert -draw "$(date -d @$now)" text_draw.gif
答案4
有一个项目叫假时间它会帮你完成这个任务。它使用 LD_PRELOAD 并使用绝对/相对时间。
libfaketime intercepts various system calls which programs use to
retrieve the current date and time. It can then report faked dates and times
(as specified by you, the user) to these programs. This means you can modify
the system time a program sees without having to change the time system-wide.
libfaketime allows you to specify both absolute dates (e.g., 01/01/2004) and
relative dates (e.g., 10 days ago).
由于您已经有了一个可行的解决方案,因此该答案仅供将来参考。