쉘에서 프로그램 실행 시간 가져 오기


407

몇 가지 다른 조건에서 Linux 쉘에서 무언가를 실행하고 각 실행의 실행 시간을 출력 할 수 있기를 원합니다.

나는 이것을 할 perl 또는 python 스크립트를 작성할 수 있다는 것을 알고 있지만 쉘에서 그것을 할 수있는 방법이 있습니까? (이것은 bash 일 것입니다)



Ticks창문 케이스와 같은 것을 얻을 수 있습니까?
freeforall tousez

답변:


534

내장 time키워드를 사용하십시오 .

$ 도움 시간

시간 : 시간 [-p] PIPELINE
    PIPELINE을 실행하고 실시간, 사용자 CPU 시간,
    PIPELINE이 종료 될 때 시스템 CPU 시간을 소비했습니다.
    반환 상태는 PIPELINE의 반환 상태입니다. `-p '옵션
    타이밍 요약을 약간 다른 형식으로 인쇄합니다. 이것은 사용
    출력 형식으로서의 TIMEFORMAT 변수의 값

예:

$ time sleep 2
실제 0m2.009s
사용자 0m0.000s
시스 0m0.004s

1
이것은 같은 명령에서 어떻게 사용 time -p i=x; while read line; do x=x; done < /path/to/file.txt됩니까? while 루프 앞에 아무것도 넣지 않으면 즉시 0.00을 반환합니다.
natli

이것은 나쁜 '시간'버전입니다 .bash 내장. 외부 '시간'명령은 어디에 있습니까?
Znik

6
@Znik, / usr / bin / time 시도
Mark Rajcok 2016 년

10
@natli : timeBash 키워드 로 인해 전체 파이프 라인을 그대로 시간을 정할 수는 있지만 그룹 명령 ( { ...; ...; })을 사용하여 여러 명령의 시간을 time -p { i=x; while read line; do x=x; done < /path/to/file.txt; }
정해야

2
시스템에 설치 한 모든 버전의 시간을 보려면 다음을 사용하십시오.type -a time
spinup

120

time (1)을time 사용하여 bash 내장 (Robert Robert가 언급 한 것) 보다 훨씬 자세한 정보를 얻을 수 있습니다 . 일반적으로 이것은입니다 ./usr/bin/time

편집자 주 : 쉘의 키워드가 아닌 외부 유틸리티 를 호출하려면 이를로 호출하십시오 . A는 POSIX 위임 유틸리티 하지만 지원하는 데 필요한 유일한 옵션이다 . : 특정 플랫폼은 특정 비표준 확장 구현 과 작품 GNU 의 (질문이 태그가 아래에서 입증 된 바와 같이, 유틸리티를timetime /usr/bin/time
time-p
-vtime); BSD / macOS 구현은 -l비슷한 출력을 생성 하는 데 사용 합니다 man 1 time.

자세한 출력 예 :


$ /usr/bin/time -v sleep 1
       Command being timed: "sleep 1"
       User time (seconds): 0.00
       System time (seconds): 0.00
       Percent of CPU this job got: 1%
       Elapsed (wall clock) time (h:mm:ss or m:ss): 0:01.05
       Average shared text size (kbytes): 0
       Average unshared data size (kbytes): 0
       Average stack size (kbytes): 0
       Average total size (kbytes): 0
       Maximum resident set size (kbytes): 0
       Average resident set size (kbytes): 0
       Major (requiring I/O) page faults: 0
       Minor (reclaiming a frame) page faults: 210
       Voluntary context switches: 2
       Involuntary context switches: 1
       Swaps: 0
       File system inputs: 0
       File system outputs: 0
       Socket messages sent: 0
       Socket messages received: 0
       Signals delivered: 0
       Page size (bytes): 4096
       Exit status: 0


2
어떤 데비안 꾸러미가 나올지 알지 못합니까? 기본적으로 설치되지 않는 것 같습니다
ʞɔıu

1
나는 당신의 로버트를 언급하고있었습니다. 당신이 제안하는 명령이 bash 내장이 아닌 것을 의미하지 않는다면?
grepsedawk

24
놀랍게도 "time"이라는 패키지에서 설치됩니다.
Paul Tomblin

2
/ usr / bin / time의 출력은 "0.00user 0.00system 0 : 02.00 0 % CPU (0avgtext + 0avgdata 0maxresident) k 0inputs + 0outputs (0major + 172minor) pagefaults 0swaps"와 유사합니다.
Paul Tomblin

4
@Nick : "sudo apt-get 설치 시간".
Robert Gamble

79
#!/bin/bash
START=$(date +%s)
# do something
# start your script work here
ls -R /etc > /tmp/x
rm -f /tmp/x
# your logic ends here
END=$(date +%s)
DIFF=$(( $END - $START ))
echo "It took $DIFF seconds"

14
훨씬 간단한 방법이 있습니다. Bash는 자동으로 특수 변수 $ SECONDS를 계산 한 다음 외부 날짜 명령을 기반으로 다시 계산할 필요가 없습니다. $ SECONDS 변수는 bash 스크립트가 시작될 때 몇 초 동안 실행되는지 유지합니다. 이 변수에는 특별한 속성이 있습니다. 매뉴얼 페이지 참조 : D
Znik

의견에서 위의 방법을 모두 시도했습니다. 1 일에 '불법 변수'오류가 발생하고 2 일에 '미확인 변수'가 발생합니다
DrBwts

45

라인 별 델타 측정의 경우 gnomon을 시도하십시오 .

타임 스탬프 정보를 다른 명령의 표준 출력에 추가하기위한 명령 줄 유틸리티 (moreutils의 ts와 약간 비슷 함). 오래 걸리는 것에 대한 역사적 기록을 원하는 장기 실행 프로세스에 유용합니다.

--high및 / 또는 --medium옵션을 사용하여 gnomon이 타임 스탬프를 빨간색 또는 노란색으로 강조 표시하는 길이 임계 값을 초 단위로 지정할 수 있습니다 . 그리고 다른 것들도 할 수 있습니다.

예


3
훌륭한 팁이지만 명확하게 말하면 : 이것은 라인 별 타이밍 유용 하지만, 세밀한 타이밍의 오버 헤드가 전체 타이밍에 크게 추가됩니다 .
mklement0

2
멋진 유틸리티 .. 공유 주셔서 감사합니다
Kishan B

19

더 정확한 결과를 원하면 %Nwith를 사용하십시오 date( 정수만 처리 bc하기 때문에 diff에 사용 하십시오 $(())).

방법은 다음과 같습니다.

start=$(date +%s.%N)
# do some stuff here
dur=$(echo "$(date +%s.%N) - $start" | bc)

printf "Execution time: %.6f seconds" $dur

예:

start=$(date +%s.%N); \
  sleep 0.1s; \
  dur=$(echo "$(date +%s.%N) - $start" | bc); \
  printf "Execution time: %.6f seconds\n" $dur

결과:

Execution time: 0.104623 seconds

15

나중에 계산에 시간을 사용하려는 경우 시간 을 절약하는 코드 를 출력 하는 -f옵션 을 사용하는 방법을 배우십시오 . 다음은 최근에 전체 클래스의 학생 프로그램의 실행 시간을 얻고 정렬하는 데 사용한 몇 가지 코드입니다./usr/bin/time

fmt="run { date = '$(date)', user = '$who', test = '$test', host = '$(hostname)', times = { user = %U, system = %S, elapsed = %e } }"
/usr/bin/time -f "$fmt" -o $timefile command args...

나중에 모든 $timefile파일을 연결 하고 출력을 Lua 인터프리터 로 파이프합니다 . Python 또는 bash 또는 원하는 구문을 사용하여 동일한 작업을 수행 할 수 있습니다. 나는이 기술을 좋아한다.


참고 : 전체 경로 /usr/bin/time가 필요 which time합니다. 그렇지 않으면 달리 실행하더라도 time쉘 버전을 실행하여 time인수를 허용하지 않기 때문에 전체 경로 가 필요 합니다 .
Kevin Dice

나는 함께 갈 것입니다 env time:-)
치로 틸리郝海东冠状病六四事件法轮功

13

$SECONDS초 단위의 정밀도 만 필요한 경우 내장 변수를 사용 하면 셸이 실행 된 시간 (초)을 계산합니다.

while true; do
    start=$SECONDS
    some_long_running_command
    duration=$(( SECONDS - start ))
    echo "This run took $duration seconds"
    if some_condition; then break; fi
done

10

당신은 사용할 수 있습니다 time서브 쉘 () :

time (
  for (( i=1; i<10000; i++ )); do
    echo 1 >/dev/null
  done
)

또는 같은 쉘에서 {}:

time {
  for (( i=1; i<10000; i++ )); do
    echo 1 >/dev/null
  done
}

두 개의 동일한 코드 스 니펫을 게시했습니다. 거기에 다른 무언가가 있어야합니다.
stason

3
@StasBekman은 처음에는 (& )(새로운 컨텍스트, 서브 쉘 )를 사용하고 {& }(같은 쉘, 동일한 컨텍스트)를 사용하는 다른 사실이 아닙니다.
Eduardo Cuomo

아하! 나는 둘을 정말로 열심히보고 있었고 그 차이를 보지 못했습니다. {} 대 ()를 명확히 해 주셔서 감사합니다.
stason

2

방법은

$ > g++ -lpthread perform.c -o per
$ > time ./per

출력은 >>

real    0m0.014s
user    0m0.010s
sys     0m0.002s

사용에 대한 필요가 없습니다 -lphtread또는 -o태그입니다. time수락 된 답변이 더 잘 설명되어있는 명령 을 사용해야합니다 .
데니스

7
예를 들어, 내 perform.c에 스레딩이 있으므로 -lpthread가 필요하고 간단한 ID의 경우 -o per입니다.
Robel Sharma

0

다른 사용자 요구를 충족시키지 못하는 간단한 방법 중 하나는 쉘 PROMPT를 사용하는 것입니다. 경우에 따라 유용한 간단한 솔루션입니다. 아래 예와 같이 bash 프롬프트 기능을 사용할 수 있습니다.

내보내기 PS1 = '[\ t \ u @ \ h] \ $' 

위의 명령은 쉘 프롬프트를 다음과 같이 변경합니다.

[HH : MM : SS username @ hostname] $ 

쉘 프롬프트로 되돌아가는 명령을 실행하거나 Enter 키를 누를 때마다 프롬프트에 현재 시간이 표시됩니다.

주 :
1) 다음 명령을 입력하기 전에 언젠가 기다렸다면이 시간을 고려해야합니다. 즉, 쉘 프롬프트에 표시된 시간은 명령을 입력 할 때가 아니라 쉘 프롬프트가 표시된 시간 소인입니다. 일부 사용자는 Enter 키를 눌러 다음 명령을 준비하기 전에 새 타임 스탬프가 포함 된 새 프롬프트를 표시합니다.
2) bash 프롬프트를 변경하는 데 사용할 수있는 다른 옵션 및 수정자가 있습니다. 자세한 내용은 (man bash)를 참조하십시오.


프로그램이 실행될 시점이 아니라 프로그램 실행 기간.
Geno Chen
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.