파이프라인 명령의 개별 실행 상태

파이프라인 명령의 개별 실행 상태

echo $?명령에는 출력을 추가로 리디렉션하기 위한 많은 파이프가 있습니다. 전체 명령의 전체 상태가 아니라 절반 실행까지 또는 특정 수의 파이프까지 파이프 값을 알 수 있는 방법이 있습니까 ? 예를 들어 다음 명령을 실행하여 다음과 같이 에포크 시간으로 변환할 파일의 타임스탬프를 가져옵니다.

`ls -lrt --time-style=+"%b %d %Y %H:%M:%S" /some/path/*.dat|head -1|tr -s " "|cut -d " " -f 9|date --date - +%s`

하지만 수동으로 반으로 나누었는지 확인했기 때문에 원하는 것을 얻지 못했습니다.

var1=`ls -lrt --time-style=+"%b %d %Y %H:%M:%S" /some/path/*.dat|head -1|tr -s " "|cut -d " " -f 9`
var2=`date --date=$var1 +%s`

첫 번째 완전한 명령에서는 여전히 오류 없이 출력됩니다. 이는 예상한 것과는 다르지만 두 개의 명령을 사용하고 싶지도 않습니다. 누구든지 이 작업을 수행하는 방법을 제안할 수 있습니까? 아니면 정확히 어디에서 잘못되고 있습니까?

고쳐 쓰다: 다음이 오늘의 자정 시대를 생성하는 이유( -이전 파이프라인 출력을 얻기 위해 날짜가 제공되면 어떻게 될까요? 비록 그렇게 작동하지는 않지만) 첫 번째 질문에도 답이 없습니다.

-bash-3.2$ ls -lrt --time-style=+"%b %d %Y %H:%M:%S" *.dat|head -1|tr -s " "|cut -d " " -f9|date --date - +%s; date +%s
1429056000      #Midnight's
1429093077      #Current

PS: 지금은 그런 시대가 아닙니다.

답변1

명령에는 출력을 추가로 리디렉션하기 위한 많은 파이프가 있습니다. echo $의 값을 알 수 있는 방법이 있습니까? 전체 명령이 아닌 실행 중간까지 또는 일정 수의 파이프까지의 전체 상태입니까?

PIPESTATUSBash에는 최근 파이프라인의 각 명령 종료 상태를 포함하는 배열인 변수가 있습니다 .

$ ls -lrt --time-style=+"%b %d %Y %H:%M:%S" /bin/*|head -1|tr -s " "| \
  cut -d " " -f 9|date --date - +%s
1429070400
$ echo ${PIPESTATUS[@]}
141 0 0 141 0
$ kill -l `expr 141 - 128`
PIPE

이는 파이프라인의 다음 명령에 의해 출력이 완전히 소비되지 않기 때문에 예상되는 SIGPIPE로 명령이 종료되었음을 ls알려 줍니다 .cut

첫 번째 전체 명령에서는 여전히 오류 없이 출력이 표시되는데, 이는 예상했던 것과 다릅니다.

그 이유는 date명령이 예상대로 작동하지만 예상한 대로 작동하지 않기 때문입니다.

date --date --날짜는 표준 입력에서 읽히지 않고 대신 날짜 문자열 로 사용됩니다 . alone의 의미가 어디에 기록되어 있는지는 알 수 없지만 -"낮의 자정"을 의미하는 or와 동일한 것 같습니다.00000

답변2

당신은이 명령을 가지고

ls -lrt --time-style=+"%b %d %Y %H:%M:%S" /some/path/*.dat|head -1|tr -s " "|cut -d " " -f 9|date --date - +%s

문제는 date해당 매개변수가 전달되기를 원하지 않는다는 것입니다.표준 입력이므로 두 부분으로 나누어야 합니다. 질문의 두 번째 부분에서 이미 이것을 시도했습니다.

var1=$(ls -lrt --time-style=+"%b %d %Y %H:%M:%S" /some/path/*.dat|head -1|tr -s " "|cut -d " " -f 9)
echo "var1='$var1'"    # eg var1='11:37:39'
var2=$(date --date="$var1" +%s)
echo "var2='$var2'"    # eg var2='1429094259'

그러나 date명령을 실행하면 시간이 표시됩니다(11:37:39 - 1429094259).오늘(이것을 내 값인 11:04:45 - 1429092286과 비교하면 var2매우 유사하다는 것을 알 수 있습니다.)

어쩌면 stat --format '%Y' /tmp/path/*.dat더 쉬울까요?


특정 질문에 대한 일부 답변

echo $의 값을 알 수 있는 방법이 있나요? [파이프 중앙 건너편]?직접적으로는 아닙니다. 그러나 파이프라인을 두 부분으로 분할하고 임시 파일을 사용하여 중간 결과를 저장하거나 $?언제든지 값을 저장할 수 있습니다.

cmd1 | ( cmd2; SS=$?; echo $SS >/tmp/cmd2.ss; exit $SS ) | cmd3
cmd2_status=$(</tmp/cmd2.ss)

단일 파이프라인에서 원하는 것을 어떻게 달성할 수 있나요?시간을 평가하고 다음과 같이 날짜로 전달할 수 있습니다.

date --date=$( cmd1 | cmd2 | cmd2 ) +%s

date --date=-자정시간은 왜 만들어졌나요?date명령은 유효하지 않은 날짜 "-"를 사용하여 의미 있는 작업을 수행하려고 합니다. 공교롭게도 이것은 결국 "오늘 자정"으로 해석됩니다. 하지만 나는 그것을 믿지 않을 것입니다. 정말로 자정을 원한다면 나는 명시적인 것을 선택하겠습니다date --date='00:00'

관련 정보