함수를 호출하는 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/output
Bash에서는 >(...)
괄호 사이의 모든 항목이 실행되고 >(...)
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 독립적이어야 하지만 bash
OS에 특정한 변형은 다음과 같습니다.
exec 3>&1
ls | sort | tee >( cat >&3 ) | rev > /tmp/output
에서는 bash
실행 중인 프로세스의 파이프를 가리키는 파일 핸들을 제공합니다.>(command)
command
. 어떤(?) 쉘에서 다음을 실행하십시오.command >&fd
command
표준 출력은 이전에 설정되어 있어야 하는 지정된 파일 설명자로 리디렉션됩니다.
모든 *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
이러한 답변은 출력을 표준 출력에 기록하도록 명령을 간단히 재정렬할 수 있다는 점에서 유연합니다 .