다음과 같은 명령이 있다고 가정해 보겠습니다.
foo() {
echo a
echo b >&2
echo c
echo d >&2
}
다음 명령을 사용하여 터미널에서 stdout을 처리하고 있는데 알림을 통해 오류가 전송됩니다.
foo 1> >(cat) 2> >(ifne notify-send "Error")
b d
내가 겪고 있는 문제는 stderr(이 경우 )을 알림 전송 본문으로 처리하고 싶다는 것입니다 .
나는 시도했다:
foo 1> >(cat) 2> >(ifne notify-send "Error" "$(cat)")
foo 1> >(cat) 2> >(ifne notify-send "Error" "$(</dev/stdin)")
아무것도 작동하지 않습니다. 여기서 해결책은 무엇입니까?
답변1
시도하면 "$(cat)"
거의 다 왔지만 따라가 아니라 cat
에서 읽어야 합니다 .ifne
ifne
ifne notify-send "Error" "$(cat)"
의 경우 cat
동일한 스트림에서 읽기가 이루어지지만 ifne
동시에는 이루어지지 않습니다. 코드의 이 부분을 처리하는 셸은 ifne
종료한 후에만 실행할 수 있습니다 . 왜냐하면 그 후에만 확장해야 할 항목, 즉 어떤 인수를 가져와야 하는지 cat
알 수 있기 때문 입니다. 종료 후 스트림은 모두 소모되고 해당 입력은 비어 있습니다.$(cat)
fine
cat
ifne
다음을 사용하여 cat
읽기를 수행하는 방법 은 다음과 같습니다 ifne
.
foo 2> >(ifne sh -c 'exec notify-send "Error" "$(cat)"')
(무슨 목적인지 잘 모르겠습니다 1> >(cat)
. 건너뛰었습니다.)
이는 ifne
(조건부로) 실행 중인 모든 항목의 표준 입력에 입력을 전달합니다. 이지만 실행되는 모든 항목 sh
은 sh
표준 입력을 공유합니다. cat
에서 효과적으로 읽습니다 ifne
. 시도와 마찬가지로 종료한 후에 exec notify-send
만 cat
실행할 수 있으므로 notify-send
표준 입력에서 읽으려고 해도 cat
모든 것이 먼저 소모됩니다.
너무 많은 데이터가 전달되면 이 방법이 실패할 수 있습니다 cat
. 매개변수 목록은 임의로 길 수 없습니다. 그리고 cat
종료 후에만 종료되므로 foo
이 방법은 종료 시 잘 작동하며 foo
stderr에 너무 많은 메시지를 생성하지 않습니다.
장기적으로 사용하는 대신 사용하는 xargs
것이 좋습니다.$(cat)
foo
가끔오류 줄이 생성됩니다. 이에 대한 예는 다음과 같습니다 foo
.
foo() {
echo a
echo b >&2
sleep 10
echo c
echo d >&2
sleep 20
}
이 경우 위의 해결 방법이 반드시 좋은 것은 아닙니다 foo
(한 번 시도해 보세요). 그것 과는 xargs
다릅니다 . foo
무한정 실행될 수도 있으며 오류가 있으면 즉시 알림을 받습니다(한 번에 한 줄씩). ( )를 xargs
지지 한다면 그럴 필요는 없습니다 . 다음은 명령 예입니다 .--no-run-if-empty
-r
ifne
xargs
foo 2> >(xargs -r -I{} notify-send "Error" {})
(이것은 xargs
여전히 따옴표와 백슬래시를 해석합니다.)