Я предполагаю, что решение Вашей проблемы в другом месте: необходимо записать сценарий, который показывает все фоновые процессы и соответствующее screen
окно.
Если бы это - опция для Вас, я предложил бы некоторый код.
Архемар объяснил, почему это не удалось на [
, вот еще один способ сделать эту конкретную замену:
$ 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
исходный код .
На самом деле существует также пакет с именем coreutils-date
! Не знал об этом! Там включены все стандартные функциональные возможности!
Если у вас есть компилятор 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.
Миллисекунды закруглены от микросекунтов.
На 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).
#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.
Решение 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 с миллисекундами!
Я обнаружил, что могу получить информацию о времени с точностью до сотых долей секунды из /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 с. (В моей системе он достаточно последователен, так что вы можете запустить его несколько раз и вычесть это значение.)