기본 제공 시간이 파이프라인에서 작동하지 않는 이유는 무엇입니까?

기본 제공 시간이 파이프라인에서 작동하지 않는 이유는 무엇입니까?

다음과 같은 샘플 스크립트가 있습니다.

#!/usr/bin/env bash
sleep 5
printf "times cmd: "
times
printf "pipeline: "
times | ( read user sys; echo $user; )
printf "head: "
times | head -n1
printf "times cmd again: "
times

출력은 다음과 같습니다.

$ ./test.sh 
times cmd: 0m0.003s 0m0.005s
0m0.001s 0m0.001s
pipeline: 0m0.000s
head: 0m0.000s 0m0.000s
times cmd again: 0m0.003s 0m0.006s
0m0.003s 0m0.004s

문제는 times명령이 파이프와 함께 사용될 때 시간을 재설정하는 이유는 무엇입니까? 값을 구문 분석하는 것을 방지할 수 있는 방법이 있습니까?

답변1

파이프라인에서는 모든 명령이 서브셸에서 실행됩니다. times쉘과 그 하위 쉘에서 소요된 시간을 보고하지만 상위 쉘에서는 그렇지 않습니다.

프로세스 대체를 시도해 볼 수 있습니다.

times > >( head -n1 )
times > >( read user sys ; echo $user )

답변2

우리가 말하는 쉘이 무엇인지에 대한 질문입니다.
이 셸에서는 다음을 얻습니다.

$ times
0m9.805s 0m3.372s
39m29.072s 0m15.537s

왜냐하면 그것은 오랫동안 실행되어 왔기 때문입니다.
그러나 서브셸은 0을 보고합니다.

$ ( times )
0m0.000s 0m0.000s
0m0.000s 0m0.000s

그리고 파이프라인의 각 부분이 서브셸에서 실행될 때:

$  sleep 10 | times
0m0.000s 0m0.000s
0m0.000s 0m0.000s

위 명령을 실행하면 times출력이 즉시 표시되고(파이프에 의존하지 않기 때문에) 10초 후에 쉘 프롬프트가 반환됩니다.

해결책?

"이" 셸에 머무르세요.

$ times > >(read user sys; echo "$user") 

그러면 왜 시간이 걸리나요? time아니면 더 강력한 것이 /usr/bin/time당신에게 도움이 될까요?

사용 시간:

$ TIMEFORMAT="%R;%U;%S"; time { sleep 1; }
1.001;0.000;0.000
$ TIMEFORMAT="%U"; time { sleep 1; }         #### If you only want user.
0.000

여러 프로세스를 중괄호로 묶습니다.

$ time { wc /etc/hosts; sleep 2; }
 21 115 327 /etc/hosts

real    0m2.003s
user    0m0.000s
sys     0m0.000s

더 강력한 external을 사용하세요 time(슬프게도 외부 실행 파일에서만 작동합니다).

$ /usr/bin/time wc /etc/hosts
 21 115 327 /etc/hosts
0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext+0avgdata 534maxresident)k
0inputs+0outputs (0major+109minor)pagefaults 0swaps

관련 정보