stderr를 stdout으로 리디렉션하여 스크립트의 파일로 리디렉션

stderr를 stdout으로 리디렉션하여 스크립트의 파일로 리디렉션

프로토타입을 작성해야 하는 여러 가지 알고리즘이 있습니다.

그래서 프로토타입과 스크립트를 만들었어요. 호출된 스크립트는 time.sh다음과 같습니다.

echo "Timing algorithm1:"
time algo1 >dev/null

echo "Timing algorithm2:"
time algo2 >dev/null

echo "Timing algorithm3:"
time algo3 >dev/null

...

이제 단순화를 위해 ... ls로 바꾸십시오 algo1. (모든 알고리즘에 대한 코드를 게시하고 사람들이 이를 컴파일하도록 강요하고 싶지는 않습니다...)

echo " Timing ls"
time ls 2>&1 > /dev/null

불러라time_ls.sh

그럼 내가

sh time_ls.sh > ls_sh.meas

내가 무엇을 하든, 스크립트나 명령줄에 어떤 리디렉션을 입력하든 두 가지 결과 중 하나를 얻습니다. 터미널에서 "Timing ls"라는 echo 출력을 얻거나 ls_sh.meas반대 타이밍 데이터를 얻습니다.

이는 stdout과 stderr이 함께 모여 아기 데이터 파일을 생성하기를 원하지 않는 것과 같습니다.

누구든지 이 이상한 동작을 설명하고 해결 방법을 제안할 수 있습니까?

추신: 이것은 bash에서 수행됩니다.

답변1

Korn과 같은 셸에는 다음을 time소개하는 키워드가 있습니다.

time <pipeline>

구조. time파이프일 때는 파이프로 연결된 명령이다.

time for i in 1 2; do
       echo "$i"
     done 2>&1 | {
       read a
       read b
       ls /etc /x
     } 2> /dev/null
time ls 2>&1

시간 제한 파이프라인의 예입니다 time.

time파이프라인의 프로세스가 반환된 후 통계는 셸의 stderr에 보고되지만 파이프라인의 각 타이밍 부분 동안 통계 출력을 2> ...리디렉션하지는 않습니다 .time

리디렉션하려면 stderr이 필요합니다.앞으로구성 을 time ...평가합니다 . 예를 들어:

{ time <pipeline>; } 2> ...
eval 'time <pipeline>' 2> ...
exec 2> ...; time <pipeline>

time문제의 명령 오류가 아닌 출력 만 리디렉션하려면 <pipeline>이전 표준 오류를 다른 표준 오류에 저장 fd하고 클록 중인 파이프에서 복원할 수 있습니다. 예를 들어:

{
  time {
    <pipeline>
  } 2>&3 3>&-
} 3>&2 2> ...

이 출력을 다른 명령으로 파이프합니다.

{
  {
    time {
      <pipeline>
    } 2>&3 3>&-
  } 3>&2 2>&1 >&4 4>&- | another command 4>&-
} 4>&-

fd 4에 저장한 후 표준 출력도 복원해야 합니다.

모든 stdout, stderr 및 time통계를 명령에 전달하려면 다음을 수행하십시오.

{ time <pipeline>; } 2>&1 | a command

답변2

time동일한 로그 파일에 각 프로토타입의 출력과 출력을 포함하고 싶다고 생각합니다 .

#!/bin/bash
# Name as "algon1"    (
    echo "Timing algorithm1:"
    time algo1 >/dev/null
    
    echo "Timing algorithm2:"
    time algo2 >/dev/null
    
    echo "Timing algorithm3:"
    time algo3 >/dev/null
) > algon1.log 2>&1

그런 다음 파일을 실행 가능하게 만들고 호출하십시오.

chmod a+x algon1
./algon1

또는 출력 파일 이름을 스크립트에 하드코딩하지 않으려면 대신 출력을표준 출력:

#!/bin/bash
# Name as "algon2"
(
    echo "Timing algorithm1:"
    time algo1 >/dev/null
    
    echo "Timing algorithm2:"
    time algo2 >/dev/null
    
    echo "Timing algorithm3:"
    time algo3 >/dev/null
) 2>&1

그리고

chmod a+x algon2
./algon2 | tee algon2.log

두 스크립트 모두에서 알고리즘 출력에 타이밍이 포함되도록 하려면 >/dev/null각 줄에서 이를 제거할 수 있습니다.time

답변3

스크립트 시작 부분에서 리디렉션을 정의합니다.

#!/bin/bash
exec 2>&1

echo Timing ls 1
time ls &>/dev/null

echo Timing ls 2
time ls /jabberwocks &>/dev/null
./time_ls.sh > ls_sh.meas

관련 정보