방금 POSIX를 발견했습니다.date
%s
또는 %N
형식 항목이 없는 것 같습니다 . 그래서 나는 그것들을 사용할 수 없습니다. 쉘 스크립트에서 에포크 타임스탬프를 얻는 다른 방법은 무엇입니까?
답변1
정수 초의 에포크 시간의 경우 이는 다음과 같습니다.
awk 'BEGIN{srand(); print srand()}'
또는:
awk 'BEGIN{print srand(srand())}'
~처럼POSIX에서는awk
, srand()
매개변수가 없으면 현재 시간을 의사 난수 생성기의 시드로 사용합니다. 또한 이전 시드를 반환하므로 srand()
위의 두 번째 시드는 이전 시드에 사용된 에포크 시간을 반환합니다.
다음을 사용하여 소수 부분을 얻을 수 있습니다.
echo|LC_ALL=C TZ=UTC0 diff -u /dev/null - |sed -n '2s/.*\(\.[0-9]*\).*/\1/p'
POSIX는 출력 형식을 지정합니다diff -u
, 파일이 인 경우 현재 시간을 사용합니다 -
.
그러나 출력을 받기 전에 호출한 이후로 수천 또는 심지어 수백만 나노초가 경과했을 수 있으며, awk
심지어 같은 초가 아닐 수도 있습니다. 그러나 다음 <epochtime> % 60
과 비교하여 이것이 사실인지 확인할 수 있습니다.두번째diff
원하는 경우 헤더에서 (UTC) 타임스탬프의 일부로 만들 수 있습니다.
1 이 awk
솔루션과 관련하여 POSIX는 과거에 이를 표현하기 위해 많은 언어를 사용하지 않았다는 점에 유의하십시오. 내가 해냈어이의제기얼마 전 POSIX의 불명확한 표현에 대해 질문을 받았고 구현에 그렇게 열악한 엔트로피 소스를 사용하도록 강요하는 것은 오늘날에는 불합리하다고 지적했습니다. 반대로,해결하다srand()
에포크 시간을 사용하기 위한 명시적인 요구 사항입니다 .
답변2
time()
결과를 호출하고 인쇄하는 C 프로그램을 작성하십시오 . 샘플 프로그램 대여time()
기능 사양, 예를 들어 다음과 같이 부릅니다 seconds.c
.
#include <stdio.h>
#include <stdint.h>
#include <time.h>
int main(void)
{
time_t t = time(NULL);
printf("%ju\n", (uintmax_t) t);
return 0;
}
그리고 c99 -o seconds seconds.c
. (읽어보면사양맞습니다. 이것이 컴파일하는 표준 방법이어야 합니다. )
또는 분해된 날짜를 가져와 초를 계산할 수 있습니다. 하루의 길이는 86400초이므로 이는 비교적 쉽습니다. 쉘 연산이 이를 8진수로 처리하지 않도록 일부 값에서 선행 0을 제거해야 합니다.
쉘 함수로서:
epochtime() {
eval "$(date -u +'y=%Y j=%j h=%H m=%M s=%S')"
s=${s#0}
m=${m#0}
h=${h#0}
j=${j#0}
j=${j#0}
t=$(( ((y-1970)*365 + (y-1969)/4 + j - 1)*86400 + h*3600 + m*60 + s))
echo "$t"
}
윤년 계산에 대한 참고 사항: 신기원 이후 첫 번째 윤년은 1972년이고, (1972-1969)/4 = 3/4 = 0, 그리고 (1973-1969)/4 = 4/4 = 1(정수 잘림에 따라 다름) ). 따라서 (연도-1969)/4는 윤년 수를 나타냅니다.앞으로올해. 올해 가능한 윤일은 %j
"연중 일" 값에 포함됩니다. 숫자는 1부터 계산되기 시작하지만 경과된 전체 일수를 원하므로 표현식에 음수 1이 필요합니다.
답변3
date
에포크 이후 초 수 동안 POSIX 수식에 대한 셸 산술 표현식을 생성하는 사용자 정의 형식 문자열을 사용하여 이 작업을 수행할 수 있습니다 .
secs=$((`TZ=GMT0 date \
+"((%Y-1600)*365+(%Y-1600)/4-(%Y-1600)/100+(%Y-1600)/400+1%j-1000-135140)\
*86400+(1%H-100)*3600+(1%M-100)*60+(1%S-100)"`))
이 방법은 다음에서 따왔습니다.https://www.etalabs.net/sh_tricks.html