stderr이 존재하는 경우 알림 전송을 위해 알림 본문에서 stderr을 사용합니다.

stderr이 존재하는 경우 알림 전송을 위해 알림 본문에서 stderr을 사용합니다.

다음과 같은 명령이 있다고 가정해 보겠습니다.

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에서 읽어야 합니다 .ifneifne

ifne notify-send "Error" "$(cat)"의 경우 cat동일한 스트림에서 읽기가 이루어지지만 ifne동시에는 이루어지지 않습니다. 코드의 이 부분을 처리하는 셸은 ifne종료한 후에만 실행할 수 있습니다 . 왜냐하면 그 후에만 확장해야 할 항목, 즉 어떤 인수를 가져와야 하는지 cat알 수 있기 때문 입니다. 종료 후 스트림은 모두 소모되고 해당 입력은 비어 있습니다.$(cat)finecatifne

다음을 사용하여 cat읽기를 수행하는 방법 은 다음과 같습니다 ifne.

foo 2> >(ifne sh -c 'exec notify-send "Error" "$(cat)"')

(무슨 목적인지 잘 모르겠습니다 1> >(cat). 건너뛰었습니다.)

이는 ifne(조건부로) 실행 중인 모든 항목의 표준 입력에 입력을 전달합니다. 이지만 실행되는 모든 항목 shsh표준 입력을 공유합니다. cat에서 효과적으로 읽습니다 ifne. 시도와 마찬가지로 종료한 후에 exec notify-sendcat실행할 수 있으므로 notify-send표준 입력에서 읽으려고 해도 cat모든 것이 먼저 소모됩니다.

너무 많은 데이터가 전달되면 이 방법이 실패할 수 있습니다 cat. 매개변수 목록은 임의로 길 수 없습니다. 그리고 cat종료 후에만 종료되므로 foo이 방법은 종료 시 잘 작동하며 foostderr에 너무 많은 메시지를 생성하지 않습니다.

장기적으로 사용하는 대신 사용하는 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-rifnexargs

foo 2> >(xargs -r -I{} notify-send "Error" {})

(이것은 xargs여전히 ​​따옴표와 백슬래시를 해석합니다.)

관련 정보