Skip to main content
added 75 characters in body
Source Link
Kamil Maciorowski
  • 24.5k
  • 2
  • 69
  • 129

With your try with "$(cat)" you're almost there, but you need this cat to read from ifne, not along ifne.

In case of ifne notify-send "Error" "$(cat)", cat reads from the same stream ifne does, but not simultaneously. The shell handling this part of code can run ifne only after cat exits (because only then it knows what $(cat) should expand to, i.e. what arguments fine should get). After cat exits, the stream is already depleted and ifne sees its input as empty.

This is a way to make a similarly used cat read from ifne:

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

(I'm not sure what the purpose of your 1> >(cat) was. I skipped it.)

Here ifne relays its input to the stdin of whatever it (conditionally) runs. It's sh, but everything this sh runs shares its stdin. Effectively cat reads from ifne. And similarly to your try, exec notify-send can be executed only after cat exits; so even if notify-send tried to read from its stdin, cat would consume everything first.

This method may fail if there is too much data passing through cat. Argument list cannot be arbitrarily long. And because cat will exit only after foo exits, the method works for foo that ever exits and generates not too many messages to its stderr.

Using xargs instead of $(cat) may be a good idea for long-running foo that occasionally generates a line of error. This is an example of such foo:

foo() {
    echo a
    echo b >&2
    sleep 10
    echo c
    echo d >&2
    sleep 20
}

The above solution is not necessarily good in case of this foo (try it). With xargs it's different. foo may even run indefinitely and you will be notified of errors (one line at a time) immediately. If your xargs supports --no-run-if-empty (-r) then you don't need ifne. This is an example command with xargs:

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

(Note this xargs still interprets quotes and backslashes.)

With your try with "$(cat)" you're almost there, but you need this cat to read from ifne, not along ifne.

In case of ifne notify-send "Error" "$(cat)", cat reads from the same stream ifne does, but not simultaneously. The shell handling this part of code can run ifne only after cat exits (because only then it knows what $(cat) should expand to, i.e. what arguments fine should get). After cat exits, the stream is already depleted and ifne sees its input as empty.

This is a way to make a similarly used cat read from ifne:

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

(I'm not sure what the purpose of your 1> >(cat) was. I skipped it.)

Here ifne relays its input to the stdin of whatever it (conditionally) runs. It's sh, but everything this sh runs shares its stdin. Effectively cat reads from ifne. And similarly to your try, exec notify-send can be executed only after cat exits; so even if notify-send tried to read from its stdin, cat would consume everything first.

This method may fail if there is too much data passing through cat. Argument list cannot be arbitrarily long. And because cat will exit only after foo exits, the method works for foo that ever exits and generates not too many messages to its stderr.

Using xargs instead of $(cat) may be a good idea for long-running foo that occasionally generates a line of error. This is an example of such foo:

foo() {
    echo a
    echo b >&2
    sleep 10
    echo c
    echo d >&2
    sleep 20
}

The above solution is not necessarily good in case of this foo (try it). With xargs it's different. foo may even run indefinitely and you will be notified of errors (one line at a time). If your xargs supports --no-run-if-empty (-r) then you don't need ifne. This is an example command with xargs:

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

With your try with "$(cat)" you're almost there, but you need this cat to read from ifne, not along ifne.

In case of ifne notify-send "Error" "$(cat)", cat reads from the same stream ifne does, but not simultaneously. The shell handling this part of code can run ifne only after cat exits (because only then it knows what $(cat) should expand to, i.e. what arguments fine should get). After cat exits, the stream is already depleted and ifne sees its input as empty.

This is a way to make a similarly used cat read from ifne:

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

(I'm not sure what the purpose of your 1> >(cat) was. I skipped it.)

Here ifne relays its input to the stdin of whatever it (conditionally) runs. It's sh, but everything this sh runs shares its stdin. Effectively cat reads from ifne. And similarly to your try, exec notify-send can be executed only after cat exits; so even if notify-send tried to read from its stdin, cat would consume everything first.

This method may fail if there is too much data passing through cat. Argument list cannot be arbitrarily long. And because cat will exit only after foo exits, the method works for foo that ever exits and generates not too many messages to its stderr.

Using xargs instead of $(cat) may be a good idea for long-running foo that occasionally generates a line of error. This is an example of such foo:

foo() {
    echo a
    echo b >&2
    sleep 10
    echo c
    echo d >&2
    sleep 20
}

The above solution is not necessarily good in case of this foo (try it). With xargs it's different. foo may even run indefinitely and you will be notified of errors (one line at a time) immediately. If your xargs supports --no-run-if-empty (-r) then you don't need ifne. This is an example command with xargs:

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

(Note this xargs still interprets quotes and backslashes.)

added 788 characters in body
Source Link
Kamil Maciorowski
  • 24.5k
  • 2
  • 69
  • 129

With your try with "$(cat)" you're almost there, but you need this cat to read from ifne, not along ifne.

In case of ifne notify-send "Error" "$(cat)", cat reads from the same stream ifne does, but not simultaneously. The shell handling this part of code can run ifne only after cat exits (because only then it knows what $(cat) should expand to, i.e. what arguments fine should get). After cat exits, the stream is already depleted and ifne sees its input as empty.

This is a way to make a similarly used cat read from ifne:

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

(I'm not sure what the purpose of your 1> >(cat) was. I skipped it.)

Here ifne relays its input to the stdin of whatever it (conditionally) runs. It's sh, but everything this sh runs shares its stdin. Effectively cat reads from ifne. And similarly to your try, exec notify-send can be executed only after cat exits; so even if notify-send tried to read from its stdin, cat would consume everything first.

This method may fail if there is too much data passing through cat. Argument list cannot be arbitrarily long. And because cat will exit only after foo exits, the method works for foo that ever exits and generates not too many messages to its stderr.

(I'm not sure what the purpose of your 1> >(cat) was. I skipped it.) Using xargs instead of $(cat) may be a good idea for long-running foo that occasionally generates a line of error. This is an example of such foo:

foo() {
    echo a
    echo b >&2
    sleep 10
    echo c
    echo d >&2
    sleep 20
}

The above solution is not necessarily good in case of this foo (try it). With xargs it's different. foo may even run indefinitely and you will be notified of errors (one line at a time). If your xargs supports --no-run-if-empty (-r) then you don't need ifne. This is an example command with xargs:

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

With your try with "$(cat)" you're almost there, but you need this cat to read from ifne, not along ifne.

In case of ifne notify-send "Error" "$(cat)", cat reads from the same stream ifne does, but not simultaneously. The shell handling this part of code can run ifne only after cat exits (because only then it knows what $(cat) should expand to, i.e. what arguments fine should get). After cat exits, the stream is already depleted and ifne sees its input as empty.

This is a way to make a similarly used cat read from ifne:

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

Here ifne relays its input to the stdin of whatever it (conditionally) runs. It's sh, but everything this sh runs shares its stdin. Effectively cat reads from ifne. And similarly to your try, exec notify-send can be executed only after cat exits; so even if notify-send tried to read from its stdin, cat would consume everything first.

This method may fail if there is too much data passing through cat. Argument list cannot be arbitrarily long.

(I'm not sure what the purpose of your 1> >(cat) was. I skipped it.)

With your try with "$(cat)" you're almost there, but you need this cat to read from ifne, not along ifne.

In case of ifne notify-send "Error" "$(cat)", cat reads from the same stream ifne does, but not simultaneously. The shell handling this part of code can run ifne only after cat exits (because only then it knows what $(cat) should expand to, i.e. what arguments fine should get). After cat exits, the stream is already depleted and ifne sees its input as empty.

This is a way to make a similarly used cat read from ifne:

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

(I'm not sure what the purpose of your 1> >(cat) was. I skipped it.)

Here ifne relays its input to the stdin of whatever it (conditionally) runs. It's sh, but everything this sh runs shares its stdin. Effectively cat reads from ifne. And similarly to your try, exec notify-send can be executed only after cat exits; so even if notify-send tried to read from its stdin, cat would consume everything first.

This method may fail if there is too much data passing through cat. Argument list cannot be arbitrarily long. And because cat will exit only after foo exits, the method works for foo that ever exits and generates not too many messages to its stderr.

Using xargs instead of $(cat) may be a good idea for long-running foo that occasionally generates a line of error. This is an example of such foo:

foo() {
    echo a
    echo b >&2
    sleep 10
    echo c
    echo d >&2
    sleep 20
}

The above solution is not necessarily good in case of this foo (try it). With xargs it's different. foo may even run indefinitely and you will be notified of errors (one line at a time). If your xargs supports --no-run-if-empty (-r) then you don't need ifne. This is an example command with xargs:

foo 2> >(xargs -r -I{} notify-send "Error" {})
added 904 characters in body
Source Link
Kamil Maciorowski
  • 24.5k
  • 2
  • 69
  • 129

With your try with "$(cat)" you're almost there, but you need this cat to read from ifne, not along ifne.

In case of ifne notify-send "Error" "$(cat)", cat reads from the same stream ifne does, but not simultaneously. The shell handling this part of code can run ifne only after cat exits (because only then it knows what $(cat) should expand to, i.e. what arguments fine should get). After cat exits, the stream is already depleted and ifne sees its input as empty.

This is a way to make a similarly used cat read from ifne:

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

Here ifne relays its input to the stdin of whatever it (conditionally) runs. It's sh, but everything this sh runs shares its stdin. Effectively cat reads from ifne. And similarly to your try, exec notify-send can be executed only after cat exits; so even if notify-send tried to read from its stdin, cat would consume everything first.

This method may fail if there is too much data passing through cat. Argument list cannot be arbitrarily long.

(I'm not sure what the purpose of your 1> >(cat) was. I skipped it.)

With your try with "$(cat)" you're almost there, but you need this cat to read from ifne, not along ifne. This is a way:

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

(I'm not sure what the purpose of your 1> >(cat) was. I skipped it.)

With your try with "$(cat)" you're almost there, but you need this cat to read from ifne, not along ifne.

In case of ifne notify-send "Error" "$(cat)", cat reads from the same stream ifne does, but not simultaneously. The shell handling this part of code can run ifne only after cat exits (because only then it knows what $(cat) should expand to, i.e. what arguments fine should get). After cat exits, the stream is already depleted and ifne sees its input as empty.

This is a way to make a similarly used cat read from ifne:

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

Here ifne relays its input to the stdin of whatever it (conditionally) runs. It's sh, but everything this sh runs shares its stdin. Effectively cat reads from ifne. And similarly to your try, exec notify-send can be executed only after cat exits; so even if notify-send tried to read from its stdin, cat would consume everything first.

This method may fail if there is too much data passing through cat. Argument list cannot be arbitrarily long.

(I'm not sure what the purpose of your 1> >(cat) was. I skipped it.)

Source Link
Kamil Maciorowski
  • 24.5k
  • 2
  • 69
  • 129
Loading