bash 스크립트는 파이프의 표준 출력에 어떻게 작성합니까? [복사]

bash 스크립트는 파이프의 표준 출력에 어떻게 작성합니까? [복사]

함수를 호출하는 bash 스크립트가 있습니다. 무엇보다도 이 함수는 출력을 수신하는 파이프를 실행합니다. 단순화하기 위해 다음은 인위적인 예입니다.

#!/bin/bash
func() {
  ls "$@" | sort | rev > /tmp/output
}
func "$@"

그런 다음 실행하기 위해 그런 작업을 수행합니다. 해당 작업을 수행하고 페이로드를 파일에 전달합니다. 화면에 출력이 없습니다.

$ ./myscript .

sort이제 출력을 표준 출력으로 원한다고 가정해 보겠습니다. 어떻게 해야 하나요?

나는 이것을 다음과 같이 달성할 수 있다:

ls "$@" | sort | tee /dev/tty | rev > /tmp/output

그러나 다음을 /dev/tty사용하는 것은 잘못된 것입니다.

$ ./myscript > myfile

함수 내의 파이프 내부에서 bash 스크립트의 표준 출력을 참조하는 더 올바른 방법이 있습니까?

(저는 Arch Linux에서 bash 4.3.0을 사용하고 있습니다)

답변1

내가 생각할 수 있는 가장 간단한 방법은 다음과 같습니다.

ls "$@" | sort | tee >(rev > /tmp/output)

tee사본은 STDOUT으로 전송 되며 , 그 뒤에 더 이상 a가 없으므로 |이것이 상속됩니다. 즉, 리디렉션이 없으면 TTY로 이동하고, myfile그렇다면 TTY로 이동합니다. 또 다른 복사본이 해당 STDIN
으로 전송됩니다 . rev > /tmp/outputBash에서는 >(...)괄호 사이의 모든 항목이 실행되고 >(...)STDIN에 연결된 파이프 경로로 대체됩니다.

답변2

이에 대한 다른 대답은 명확하지 않기 때문에 또 다른 (대체) 접근 방식은 다음과 같습니다.

exec 3>&1
ls | sort | tee /dev/fd/3 | rev > /tmp/output

이것exec 3>&1 반복하다파일 설명자 1(stdout)을 파일 설명자 3으로 지정합니다. 그런 다음 출력 tee /dev/fd/3복사본이 sort해당 파일 설명자에 기록됩니다. 이는 모든 셸에서 작동하지만 운영 체제에 따라 다를 수 있습니다. OS 독립적이어야 하지만 bashOS에 특정한 변형은 다음과 같습니다.

exec 3>&1
ls | sort | tee >( cat >&3 ) | rev > /tmp/output

에서는 bash실행 중인 프로세스의 파이프를 가리키는 파일 핸들을 제공합니다.>(command)command. 어떤(?) 쉘에서 다음을 실행하십시오.command >&fdcommand 표준 출력은 이전에 설정되어 있어야 하는 지정된 파일 설명자로 리디렉션됩니다.

모든 *nix(Posix) 시스템에서 작동하는 보다 정교한 버전은 다음과 같습니다.

pipe_to_stdout=$(mktemp -u)
mkfifo "$pipe_to_stdout"
cat "$pipe_to_stdout" &
ls | sort | tee "$pipe_to_stdout" | rev > /tmp/output
rm "$pipe_to_stdout"

이는 두 번째 예(fifo에서 읽고 stdout에 쓰기)와 거의 동일 cat하지만 쉘 수준에서 연기와 미러를 덜 사용합니다.

ls이러한 답변은 출력을 표준 출력에 기록하도록 명령을 간단히 재정렬할 수 있다는 점에서 유연합니다 .

관련 정보