Получите секунды с начала эпохи в любой POSIX-совместимой оболочке - PullRequest
5 голосов
/ 15 марта 2010

Я хотел бы знать, есть ли способ получить количество секунд с начала эпохи UNIX в любой POSIX-совместимой оболочке, не прибегая к не-POSIX-языкам, таким как perl, или используя не-POSIX-расширения, такие как функция strftime GNU awk ,

Вот некоторые решения, которые я уже исключил ...

date +%s // Не работает на Solaris

Я видел несколько сценариев оболочки , предложенных ранее, которые анализируют вывод date, а затем выводят секунды из отформатированной даты григорианского календаря, но, похоже, они не принять во внимание детали, как високосные секунды.

GNU awk имеет функцию strftime, но она недоступна в стандартном awk.

Я мог бы написать небольшую программу на C, которая вызывает функцию time, но двоичный файл будет специфичным для конкретной архитектуры.

Существует ли кроссплатформенный способ сделать это, используя только POSIX-совместимые инструменты?

Я испытываю желание отказаться и принять зависимость от perl, который по крайней мере широко распространен.

perl -e 'время печати' // Обман (не POSIX), но должен работать на большинстве платформ

Ответы [ 3 ]

10 голосов
/ 05 октября 2012

Вот портативное / POSIX решение:

PATH=`getconf PATH` awk 'BEGIN{srand();print srand()}'

В отличие от C компилятора или Perl, awk гарантированно присутствует в POSIX-совместимой среде.

Как это работает:

  • PATH = `getconf PATH` проверяет, вызывается ли POSIX версия awk, если она не является первой в PATH .

  • В соответствии с POSIX стандартом : srand ([выражение]) Установите начальное значение для rand на expr или используйте время суток, если expr опущен. Предыдущее начальное значение должно быть возвращено.

    При первом вызове пропускается параметр, поэтому начальное значение устанавливается на время суток. Второй вызов возвращает это время суток, то есть количество секунд с начала эпохи.

    Обратите внимание, что во многих awk реализациях, но не в GNU (gawk), этот первый вызов не требуется, так как функция уже возвращает ожидаемое значение.

2 голосов
/ 31 августа 2011

Просто для образовательных целей, немного взломать. Но это такой же POSIX, как вы можете себе представить: -)

#!/bin/sh
: > x
echo "ibase=8;$(pax -wx cpio x | cut -c 48-59)" | bc
rm x

Посмотрим, что это печатает:

$ ./x.sh; date +%s
1314820066
1314820066
0 голосов
/ 22 августа 2012

Должен быть достаточно переносимым, но требует доступа на запись к ${.CURDIR};, возможно, его можно изменить.

Я не использовал /tmp для исполняемого файла, так как большинство людей установили /tmp noexec.

В любом случае работает на FreeBSD.

#!/bin/sh

# Portably gets the date since epoch

bn=`basename $0`
prog=`mktemp /tmp/${bn}.mktime.XXXXXXX` || exit 1
>${prog}.c cat <<EOF
#include <stdio.h>
#include <time.h>
int main() {printf("%ju", time(NULL)); return 0; }
EOF

cc ${prog}.c
time=`./a.out`
rm ${prog} a.out

echo Time since epoch = $time seconds
...