유닉스 시대 이후 밀리 초를 얻는 방법?


30

JavaScript를 사용하여 밀리 초 단위로 타임 스탬프를로드하는 html을 사용하고 있기 때문에 브라우저의 시작 시간을 측정하는 bash 스크립트를 만들고 싶습니다.

셸 스크립트에서 브라우저를 호출하기 직전에 타임 스탬프가 표시됩니다.

date +%s

문제는 초 단위로 타임 스탬프를 얻는다는 것입니다. 때로는 두 번째로 실행하면 브라우저가 1 초 이내에 시작되어 초 대신 밀리 초를 사용하여 정확하게 그 시간을 측정 할 수 있기 때문에 밀리 초 단위로 필요합니다.

bash 스크립트에서 타임 스탬프를 밀리 초 단위로 얻는 방법은 무엇입니까?

답변:


28

date +%s.%N예를 들어 1364391019.877418748. % N은 현재 초에 경과 된 나노초의 수입니다. 숫자는 9 자리이며 기본적으로 날짜가 100000000보다 작 으면 0으로 채워집니다. bash는 앞에 0이있는 숫자 를 8 진수로 취급 하므로 숫자로 수학을 수행하려는 경우 실제로 문제가됩니다 . 이 패딩은 필드 스펙에서 하이픈을 사용하여 비활성화 할 수 있습니다.

echo $((`date +%s`*1000+`date +%-N`/1000000))

신기원부터 순식간에 밀리 초를 줄 것입니다.

그러나 Stephane Chazelas가 아래 주석에서 지적했듯이 두 번의 date호출이 약간 씩 다르므로 두 번 약간 씩 다릅니다. 두 번째가 둘 사이에 롤오버 된 경우 전체 초가 계산됩니다. 그래서:

echo $(($(date +'%s * 1000 + %-N / 1000000')))

또는 최적화되었습니다 (아래 의견에 감사하지만 분명해야 함).

echo $(( $(date '+%s%N') / 1000000));

나는 그것을 시도했고 작동합니다, + 1 / 수락 감사합니다!
Eduard Florinescu

7
첫 번째 날짜와 두 번째 날짜를 실행하는 시간 사이에 수백만 나노초가 지나고 동일한 초도 아닐 수도 있습니다. 최선을 다하십시오 $(($(date +'%s * 1000 + %N / 1000000'))). 그것은 여전히별로 의미가 없지만 더 신뢰할 수 있습니다.
Stéphane Chazelas

1
날짜 (1)에 언급 된대로 제로 패딩을 끄는 방식으로 수정
Alois Mahdal

3
%NBSD와 OS X에서는 사용할 수 없습니다.
orkoden

1
왜 안돼 echo $(( $(date '+%s%N') / 1000000))?
Hitechcomputergeek

47

GNU 또는 ast-open 구현 date(또는 FEATURE_DATE_NANO옵션이 활성화 된 경우 busybox ' )을 사용하면 다음을 사용합니다.

$ date +%s%3N

유닉스 시대 이후 밀리 초를 반환합니다.


5
우아하고 좋은 +1
Eduard Florinescu

1
우아함에 대한지지
sleepycal

정말 우아합니다, +1 나처럼 당신이 %3N필요한 왼쪽 제로 패딩 (문서를 읽지 않고 ;-)을 확신하고 싶다면 할 수 있고 while sleep 0.05; do date +%s%3N; done, 필요한 제로가 거기에 있습니다.
Terry Brown

테리 감사합니다! 그러나 %3N실제로는 채워지지 않습니다. 또한 귀하의 솔루션이 0을 추가한다고 생각하지 않으며 응답을 너무 적게 지연시킵니다.
javabeangrinder

javabeangrinder, @TerryBrown의 코드는 해결책 이 아니며 %3N실제로 코드가 0으로 채워져 있는지 확인하기 위해 코드를 테스트하십시오 .
Stéphane Chazelas

10

경우에는 사람이 다른 쉘을보다 사용 bash, ksh93zsh부동 소수점이 $SECONDS당신이 할 경우 변수를 typeset -F SECONDS정확하게 시간을 측정하는 것이 편리 할 수있는을 :

$ typeset -F SECONDS=0
$ do-something
something done
$ echo "$SECONDS seconds have elapsed"
18.3994340000 seconds have elapsed

이후 버전 4.3.13 (2011) zsh$EPOCHREALTIME에 포인트 변수를 부동 특수 zsh/datetime모듈 :

$ zmodload zsh/datetime
$ echo $EPOCHREALTIME
1364401642.2725396156
$ printf '%d\n' $((EPOCHREALTIME*1000))
1364401755993

이는에서 반환 한 두 정수 (초 및 나노초)에서 파생됩니다 clock_gettime(). 대부분의 시스템에서 단일 C double부동 소수점 숫자가 보유 할 수있는 것보다 정밀도가 높기 때문에 산술 표현식에서 사용할 때 정밀도가 떨어집니다 (1970 년 첫 몇 개월 동안의 날짜 제외).

$ t=$EPOCHREALTIME
$ echo $t $((t))
1568473231.6078064442 1568473231.6078064

고정밀 시간 차이를 계산하려면 (밀리 초 이상의 정밀도가 필요할지 모르지만) $epochtime대신 초와 나노초를 두 개의 개별 요소로 포함하는 특수 배열 을 사용할 수 있습니다 .

버전 5.7 (2018)부터 strftime쉘 내장은 %N나노초 형식 인 GNU date및 a %.를 지원하여 정밀도를 지정하므로 신기원 이후의 밀리 초 수를 다음과 같이 검색 할 수도 있습니다.

zmodload zsh/datetime
strftime %s%3. $epochtime

(또는로 변수에 저장 -s var)


변수 "$ SECONDS"는 EPOCH 시간에 연결되어 있지 않습니다. 분수 부분 (밀리 초, 마이크로 초 및 나노초)은 각각 상당히 다를 수 있습니다.
이삭

8

밀리 초를 계산하는 계산을 피하기 위해 명령 행 JavaScript 인터프리터가 도움이 될 수 있습니다.

bash-4.2$ node -e 'console.log(new Date().getTime())' # node.js
1364391220596

bash-4.2$ js60 -e 'print(new Date().getTime())'       # SpiderMonkey
1364391220610

bash-4.2$ jsc -e 'print(new Date().getTime())'        # WebKit 
1364391220622

bash-4.2$ seed -e 'new Date().getTime()'              # GNOME object bridge
1364391220669

Ubuntu Eoan에서 해당 인터프리터가 포함 된 패키지 :


2

bash 5 이상에는 마이크로 초 단위의 변수가 있습니다 : $EPOCHREALTIME.

그래서:

$ echo "$(( ${EPOCHREALTIME//.} / 1000 ))"
1568385422635

에포크 (1/1/70) 이후의 시간을 밀리 초 단위로 인쇄합니다.

실패하면 날짜를 사용해야합니다. GNU 날짜 :

echo "$(date +'%s%3N')"

https://serverfault.com/a/423642/465827에 나열된 대안 중 하나

또는 brew install coreutilsOS X의 경우

또는 다른 모든 것이 실패하면이 c 프로그램을 컴파일 (gcc epochInµsec.c)하십시오 (필요에 따라 조정).

#include <stdio.h>
#include <sys/time.h>
int main(void)
{
  struct timeval time_now;
    gettimeofday(&time_now,NULL);
    printf ("%ld secs, %ld usecs\n",time_now.tv_sec,time_now.tv_usec);

    return 0;
}

외부 프로그램을 호출하면 디스크에서 읽고로드하고 시작, 실행 및 최종적으로 출력을 인쇄하는 데 시간이 필요합니다. 몇 밀리 초가 걸립니다. 그것이 외부 도구 (날짜 포함)로 달성 할 수있는 최소 정밀도입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.