Дата в миллисекундах на OpenWRT на Ардуино YUN

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

Если бы это - опция для Вас, я предложил бы некоторый код.

4
15.11.2014, 00:29
6 ответов

Архемар объяснил, почему это не удалось на [, вот еще один способ сделать эту конкретную замену:

$ sed "s/^./['/;s/.$/']/" file
['AAA','ACMEDEMO2','ACMEDEMO3','ACMEDEMO4','RENTCOGH','TESTENT','DORASINE','LOKAWINK','BBB']

Или, используя & , что означает «все, что вы только что сопоставили»:

$ sed "s/^./&'/;s/.$/'&/" file
['AAA','ACMEDEMO2','ACMEDEMO3','ACMEDEMO4','RENTCOGH','TESTENT','DORASINE','LOKAWINK','BBB']
-121--83327-

Эта опция была добавлена для адреса xterm мерцания (на некоторых установках) при изменении размеров/
Начальный патч был размещен пользователем на форумах Archlinux . Позже он был интегрирован в xterm исходный код .

-121--73376-

На самом деле существует также пакет с именем coreutils-date ! Не знал об этом! Там включены все стандартные функциональные возможности!

2
27.01.2020, 20:46

Если у вас есть компилятор C, и не можете найти ничего другого, это будет сообщать, например,

> millitime && sleep 1 && millitime
14/11/2014 9:39:49:364
14/11/2014 9:39:50:368
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>

int main (void) {
    struct timeval now;
    struct tm *parsed;

    if (gettimeofday(&now, NULL) == -1) {
        fprintf (
            stderr,
            "gettimeofday() failed: %s\n",
            strerror(errno)
        );
        return 1;
    }

    parsed = localtime((const time_t*)&now.tv_sec);
    if (!parsed) {
        fprintf (
            stderr,
            "localtime() failed: %s\n",
            strerror(errno)
        );
        return 1;
    }

    printf (
        "%d/%d/%d %d:%02d:%02d:%03d\n",
        parsed->tm_mday,
        parsed->tm_mon + 1,
        parsed->tm_year + 1900,
        parsed->tm_hour,
        parsed->tm_min,
        parsed->tm_sec,
        now.tv_usec / 1000
    );

    return 0;
}  

С GCC, просто компилируйте его GCC Wharke.c -o millitime . Если есть ошибка (которая была бы очень странной), она сообщает STDERR и выходит с статусом 1. В противном случае он сообщает stdout и выходит 0.

Миллисекунды закруглены от микросекунтов.

5
27.01.2020, 20:46

На OpenWRT, дата - это busybox, который имеет ограничения, но это, строго говоря, не одно из них. Основная проблема заключается в том, что libc (uClibc) не поддерживает это расширение GNU strftime. (Хотя и glibc тоже, подробнее об этом ниже)

По умолчанию вы должны иметь lua, но это не поможет без некоторых других модулей, не поддерживаемых по умолчанию.

hwclock вызывает gettimeofday() для сравнения/установки RTC (аппаратных часов), но не выводит субсекундное разрешение (доступ к RTC может быть достаточно медленным, что в любом случае может оказаться нецелесообразным). Кроме того, OpenWRT предоставляет только старую rdate, которая имеет только посекундное разрешение.

По-видимому, не существует простого способа получить точную временную метку непосредственно из /proc, самая полезная временная метка находится в /proc/timer_list (3-я строка), что является временем безотказной работы в наносекундах (разрешение будет зависеть от платформы).

Если ваш busybox был собран с набором CONFIG_BUSYBOX_CONFIG_ADJTIMEX, то вы должны иметь возможность использовать adjtimex для чтения часов ядра (хотя обратите внимание, что версия busybox имеет и различные аргументы , и различный вывод по сравнению со стандартным adjtimex.

Обычная версия, adjtimex -p, последняя строка вывода:

   raw time:  1416419719s 146628us = 1416419719.146628

Busybox version, adjtimex (без -p !), последние 3 строки:

   [...]
   time.tv_sec:  1416420386
   time.tv_usec: 732653
   return value: 0 (clock synchronized)

Goldilocks's - отличное решение, в предположении, что у вас есть кросс-компиляция OpenWRT (настоятельно рекомендуется!). Ваше решение coreutils-date работает, потому что, хотя coreutils знает glibc, это не только glibc. Оно поставляется со своей собственной автономной реализацией strftime (производной от glibc), и использует ее для обёртывания (через strftime_case()) лежащего в основе strftime для поддержки различных расширений (и в противном случае возвращается к версии uClibc).

Даже glibc (до текущей версии 2.23) не поддерживает %N, coreutils strftime(), полученное из канонической версии glibc, добавляет %N и %:z и некоторые другие изменения. Вариации и исправленные версии strftime() изобилуют (включая версии на bash и gawk).

8
27.01.2020, 20:46
#include <stdio.h>
#include <time.h>
void main (void){
    long            ms; 
    time_t          s; 

    struct timespec spec;
    clock_gettime(CLOCK_REALTIME, &spec);
    s  = spec.tv_sec;
    ms = (spec.tv_nsec / 1.0e6); 
    printf("%d%03d\n", s, ms);      
return 0;
}

Это на языке C и работает как coreutils-date date +% s% 3N . Он скомпилирован для роутера OpenWrt с OpenWrt-SDK.

-1
27.01.2020, 20:46

Решение adjtimex у меня не сработало, потому что я получаю сообщение adjtimex: операция не разрешена (я использую док-контейнер alpine). Но я нашел еще одно странное, но свободное от зависимостей решение, использующее nmeter, которое может отображать до микросекунд.

#-d0 means print every 0 seconds ie immediately
# head -n1 makes sure it only does it once
nmeter -d0 '%3t' | head -n1

Таким образом, объединив это с командой даты:

date -u +%FT$(nmeter -d0 '%3t' | head -n1)Z
# 2017-05-03T04:10:57.863Z

Мы получаем строку даты и времени rfc3339 UTC с миллисекундами!

0
27.01.2020, 20:46

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

Вот быстрый код sh:

read UPTIME < /proc/uptime
UPTIME="${UPTIME%%[^0-9.]*}"

Если все, что вам нужно, это таймер с точностью до сотых долей секунды, этого достаточно (нулевое время, ваша локальная эпоха, будет просто временем загрузки системы ).

В противном случае вы можете обмануть и вызвать запись в журнале:

printf '\u04' |nc $HOSTNAME 22 >/dev/null 2>&1 # trigger log entry by poking ssh
LOG="$(logread -l 1 -t)"                       # read last log entry w/ timestamp
LOG="${LOG##* 20?? \[}"                        # remove text before timestamp
echo "${LOG%%\]*}"                             # remove text after timestamp

Медиана занимает 0,026 с (; min=0,025 с, max=0,028 с, из 12 прогонов ). Также обратите внимание, что это загрязняет ваши журналы... и я не знаю, что происходит, когда журналы становятся «слишком большими» (для любого значения, которое ); имейте в виду, что журналы хранятся в памяти.

Поэтому, если вы собираетесь часто опрашивать время, вам, вероятно, следует создать только одну плохую запись в начале и объединить два вышеуказанных метода следующим образом:

get_uptime_ms() {
  local MS
  read UPTIME < /proc/uptime
  UPTIME="${UPTIME%%[^0-9.]*}" # strip the other listed time
  MS="${UPTIME##*.}0"          # extra zero turns 100ths of seconds into 1000ths
  UPTIME="${UPTIME%%.*}$MS"    # the time since boot in milliseconds
}

get_uptime_ms
printf '\u04' |nc $HOSTNAME 22 >/dev/null 2>&1  # poke ssh to trigger log entry 
NOW="$(logread -l 1 -t)"                        # last log entry, with timestamp
NOW="${NOW#* 20?? \[}"                          # remove text before timestamp
NOW="${NOW%%\]*}"                               # remove text after timestamp
MS="${NOW##*.}"                                 # just the milliseconds
NOW="${NOW%%.*}$MS"                             # append ms to s w/out dot

BOOT=$(( NOW - UPTIME ))

date_ms() {
  local S
  get_uptime_ms
  NOW=$(( BOOT + UPTIME))
  S="${NOW%???}"           # $NOW in seconds
  echo "$S.${NOW#$S}"      # put the dot back in, then append milliseconds
}

# now you can run date_ms as much as you like
# and it'll have the epoch time with millisecond precision.

date_ms
date +%s
date_ms

Это устанавливает что-то, что можно использовать в качестве исходного времени загрузки, вычитая время безотказной работы (до 100-х долей секунды )из временной метки триггера журнала (с точностью до 1000-х долей секунды ), а затем обновляя его с помощью время безотказной работы. Таким образом, это дает сотые доли секунды, а не 1000-е, но он вводит только одну дополнительную запись в logd, а другой метод не намного точнее, поскольку его запуск стоит 0,026 с. (В моей системе он достаточно последователен, так что вы можете запустить его несколько раз и вычесть это значение.)

1
27.01.2020, 20:46

Теги

Похожие вопросы