Например,

# 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 , а текст, нарисованный на изображении, абсолютно одинаков.

Является ли это возможным?

5 ответов5

5

Поскольку мне пришлось реализовать решение @ 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
2

Вы не можете остановить системные часы. Тем не менее, вы можете сделать это:

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
2

В Linux можно написать общую библиотеку, которая переопределяет time() , gettimeofday() и clock_gettime() чтобы использовать статические значения, и добавить библиотеку в $LD_PRELOAD , что обманет многие программы.

Обновление: кто-то реализовал это как datefudge .

1

Вы можете touch a b. Вы также можете touch a; touch --reference=a b.

1

Есть проект под названием faketime, который делает это для вас. Он использует 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).

Этот ответ для будущих ссылок, так как у вас уже есть рабочее решение.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .