1

I have a command that outputs a stream say adb logcat. I want to pipe that to grep until I find the first match of a certain query. At this point I want to stop the first command:

I've tried:

MY_VARIABLE=$(adb logcat | grep -m 1 'my variable (.*)')

But the problem is that the process will not stop even if grep finds the first match.

My guess is that I need to run adb logcat in nohup, pipe that command to grep, then stop it when done. But I'm not sure how to do this.

Timur Shtatland
  • 12,024
  • 2
  • 30
  • 47
Gabriel Furstenheim
  • 2,969
  • 30
  • 27
  • 3
    It will stop eventually when it gets an error writing to the pipe. It doesn't stop immediately because of output buffering. – Barmar May 26 '23 at 14:56

1 Answers1

0

You need to unbuffer the input to grep, that is unbuffer adb logcat. A similar example shows another command (a Perl one-liner that prints numbers 1-13, one after another, pausing 1 second in between numbers). Unbuffering the Perl command with $| = 1; does the trick and causes grep to return after 3 seconds instead of after the Perl command exits, which is after 13 seconds:

$ time ( perl -le 'BEGIN { $| = 1; } for ( 1..13 ) { print; sleep 1; }' | grep -m 1 '3' )
3
( perl -le 'BEGIN { $| = 1; } for ( 1..13 ) { print; sleep 1; }' | grep -m 1 )  0.01s user 0.01s system 0% cpu 3.047 total

$ time ( perl -le 'for ( 1..13 ) { print; sleep 1; }' | grep -m 1 '3' ) 
3
( perl -le 'for ( 1..13 ) { print; sleep 1; }' | grep -m 1 '3'; )  0.01s user 0.02s system 0% cpu 13.080 total

Timur Shtatland
  • 12,024
  • 2
  • 30
  • 47
  • 1
    I'm pretty sure that buffering is not the problem. In your example without unbuffering, grep is not receiving and printing the 3 until the 13s mark. However, when I run it with adb logcat, it logs the correct line and then stays attached – Gabriel Furstenheim May 29 '23 at 06:31
  • 1
    adb logcat is outputing a lot of content, so at some point the buffer should fill up, grep doesn't close after more than one hour – Gabriel Furstenheim May 29 '23 at 13:05
  • 1
    @GabrielFurstenheim is it possible that `adb logcat` is producing a single line of output and so `grep` never sees an end of line to tell it when it's done matching `.*`? If you [edit] your question to show some lines of `adb logcat` output and copy/paste what you see when you run `adb logcat | grep -m 1 'my variable (.*)'` then we can probably provide more help. – Ed Morton May 29 '23 at 13:56
  • adb logcat does produce several lines of data. It's basically streaming out logs from the android device. Sorry, cannot show those logs, since it is propietary. – Gabriel Furstenheim May 30 '23 at 13:24