Tee>( process )는 파일에 쓸 때 표준 출력을 자릅니다.

Tee>( process )는 파일에 쓸 때 표준 출력을 자릅니다.

stdout을 "특정 코드 블록"으로 직접 파이프한 다음 수정된 데이터를 파일에 쓰면 tee항상 파일에서 예상되는 출력 줄의 전체 보완을 얻습니다.

그러나 tee동일한 데이터를 프로세스에 보내면 >("same block of code")출력에서 ​​최대 4줄이 제거될 수 있습니다. 이 숫자는 다양하며 때로는 모든 줄을 작성합니다.

이 문제를 어떻게 해결할 수 있으며,에서만 발생합니까 >( process )?

추가 정보: 이 회선 손실이 발생했을 때 저는 일반 stdout 파이프뿐만 아니라 2개의 프로세스 대체를 "티잉"하고 있었습니다.

Ubuntu 10.04.2 LTS, 버전 4.1.5(1) 릴리스(i486-pc-linux-gnu)에서 GNU bash를 사용합니다.

이것이 실제 스크립트입니다. 두 번째 프로세스 대체는 문제의 프로세스입니다.>(tr $'\x60' $X01

#  
# Run 'locate' and direct the output to a temp file
  errflag=""
  locitmct=0  # Count of located items 
  columns=4  # The number of columns in the main dialog
  colmnb=0  # Column number (NB: columns 1 and 2 are processed together) 
  X01=$'\x01'
  eval locate $zenargs |tee \
      >(zenity --progress --pulsate --auto-close) \
      >(tr $'\x60' $X01 \
         |sed -n "s/^\(.*\/\)\(.*\)/\1\2\n\2\n\1/p" \
            |while IFS= read -r line ; do \
              #
              #
              # process the data
              #
              #
            done > "$listf" )\
      >/dev/null
#
cat "$listf"
#

답변1

이 질문을 한 지 10시간이 지났고 해결책을 찾았습니다... 참고: 이전에 질문 아래의 설명에서 언급했듯이 wait이러한 프로세스에서는 작동하지 않습니다. 이는 이러한 "프로세스 재정의"가 기다리고 있는 "하위" 프로세스가 아니기 때문이라고 생각합니다 wait. (매개변수 없이 시도했습니다 wait)....

기능과 단점에 대한 의견을 주시면 감사하겠습니다. stdin이 어떻게 선택 zenity되고 첫 번째 명령이 tr언제 echo인지 잘 이해가 안 되지만 그냥 시도해 보고 싶었습니다... 작동하는 것 같지만(이 경우) 이 접근 방식이 안전한가요?

이 문제를 해결하기 위해 잘 시도되고 테스트된 방법이 있을 수 있으므로 다른 답변은 그만한 가치가 있습니다.


#!/bin/bash
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# Set up flag-files for processes to send PIDs to main process
# The first thing each process does is: echo -n "$BASHPID " > flag-file  
for i in {1..2};do cp /dev/null "$listf".pid$i;done
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
eval locate $zenargs |tee \
    >(echo -n "$BASHPID " > "$listf".pid1 ; \
      zenity --progress --pulsate --auto-close) \
    >(echo -n "$BASHPID " > "$listf".pid2 ; \
      tr $'\x60' $X01 \
       |sed -n "s/^\(.*\/\)\(.*\)/\1\2\n\2\n\1/p" \
          |while IFS= read -r line ; do \
              #
              #
              # process the data 
              #
              #
          done > "$listf" ) \
    >/dev/null
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
####  WAIT for processes to terminate  
pids=$(cat "$listf".pid{1,2})
while [[ "$pids" == *[0-9]* ]] ; do
   sleep .1 # GNU
   for pid in $pids ; do
      if ! kill -0 "$pid" 2>/dev/null; then
         pids="${pids/$pid/}"
      fi
   done 
done
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
cat "$listf"
#

답변2

coreutils 버전 8.24부터 다른 방법이 있습니다.

tee -p </dev/zero >(head -c10M | wc -c ) > >(head -c1 | wc -c ) | numfmt --to=iec

출력은 다음과 같습니다

1

10M

여기서 핵심 포인트는

  1. 이를 사용하면 파이프에 오류가 아닌 모든 출력에 경고가 기록 -p됩니다 . tee즉, EPIPE 오류는 종료를 fwrite유발하지 않으며 쓰기 위해 열려 있는 출력 파일이 하나 이상 있는 한 실행됩니다. stderr 로 인쇄하는 것에 대한 EPIPE 경고를 받으려면 .teetee--output-error=warn-p

  2. > >(head -c1 | wc -c )tee의 표준 출력을 다른 출력으로 리디렉션하는 데 사용됩니다 >(process substitution). 이는 두 가지 이유로 중요합니다. 예를 들어 , stdin을 사용하는 경우 stdin에 데이터가 있는 한 실행됩니다(이 경우 영원히 실행됨) tee. 동시에 추가 처리를 위해 출력을 표준 출력으로 보낼 수 있습니다. 덜 우아하지만 또 다른 가능성 은 다른 방법으로 stdout 출력을 끄는 것입니다 . 두 가지 가능성은 및 입니다 . 그러나 이는 경고를 발행합니다(tee: stdout: 장치에 남은 공간 없음 및 tee: stdout: 각각 잘못된 파일 설명자).>/dev/nulltee>(process substitution)tee>/dev/full>&-

관련 정보