Remix.run Logo
BeefWellington 8 months ago

AFAIK, signal order generally propagates backwards, so the last command run will always receive the signal first, provided it is a foreground command.

But also, the example is not a great one; grepping tcpdump output doesn't make sense given its extensive and well-documented expression syntax. It's obviously just used as an example here to demonstrate buffering.

Joker_vD 8 months ago | parent | next [-]

> grepping tcpdump output doesn't make sense given its extensive and well-documented expression syntax

Well. Personally, every time I've tried to learn its expression syntax from its extensive documentation my eyes would start to glaze over after about 60 seconds; so I just stick with grep — at worst, I have to put the forgotten "-E" in front of the pattern and re-run the command.

By the way, and slightly off-tangent: if anyone ever wanted grep to output only some part of the captured pattern, like -o but only for the part inside the parentheses, then one way to do it is to use a wrapper like this:

    #!/bin/sh -e

    GREP_PATTERN="$1"
    SED_PATTERN="$(printf '%s\n' "$GREP_PATTERN" | sed 's;/;\\/;g')"
    shift

    grep -E "$GREP_PATTERN" --line-buffered "$@" | sed -r 's/^.*'"$SED_PATTERN"'.*$/\1/g'
Not the most efficient way, I imagine, but it works fine for my use cases (in which I never need more than one capturing group anyway). Example invocation:

    $ xgrep '(^[^:]+):.*:/nonexistent:' /etc/passwd
    nobody
    messagebus
    _apt
    tcpdump
    whoopsie
cafeinux 8 months ago | parent | next [-]

I usually use PCRE mode and prepend what I want to be displayed with `\K` (and append a lookahead if needed):

  ~ $ echo "foo bar1 baz foo bar2" | grep -oP 'foo \Kbar\d'
  bar1
  bar2
  ~ $ echo "foo bar1 baz foo bar2" | grep -oP 'foo \Kbar\d(?= baz)'
  bar1
  ~ $ echo "foo bar1 baz foo bar2" | grep -oP 'foo \Kbar\d(?=$)'
  bar2
Of course, it implies using a version of `grep` supporting the `-P` option. Notably, MacOS doesn't by default, although if -P is utterly needed, there are ways to install gnu-grep or modify the command used to achieve the same result. Your way is perhaps more cross-platform, but for my (very personal) use cases, mine is easier to remember and needs no setup.

Edit: worst case, piping to `cut` or `awk` can also be a solution.

Joker_vD 7 months ago | parent [-]

Ah, I knew about the \K to cut things before the match, but I could never find how to cut away the things after. But it exists and it's (?=... Well, better late than never.

> worst case, piping to `cut` or `awk` can also be a solution.

Yeah, I've used that too, and that's how I ended with writing the script down: constantly piping things through the second filter with yet another stupid regex that needs tinkering as well... isn't there a way to reuse the first regex, somehow? Hmm, don't the patterns in the sed's "substitute" use the same syntax as the grep does?.. They do! How convenient.

chatmasta 8 months ago | parent | prev [-]

ChatGPT has eliminated this class of problem for me. In fact it’s pretty much all I use it for. Whether it’s ffmpeg, tcpdump, imagemagick, SSH tunnels, Pandas, numpy, or some other esoteric program with its own DSL… ChatGPT can construct the arguments I need. And if it gets it wrong, it’s usually one prompt away from fixing it.

toast0 8 months ago | parent | prev [-]

> grepping tcpdump output doesn't make sense given its extensive and well-documented expression syntax.

I dunno. If doesn't make sense in the world where everyone makes the most efficient pipelines for what they want; but in that world, they also always remember to use --line-buffered on grep when needed, and the line buffered output option for tcpdump.

In reality, for a short term thing, grepping on the grepable parts of the output can be easier than reviewing the docs to get the right filter to do what you really want. Ex, if you're dumping http requests and you want to see only lines that match some url, you can use grep. Might not catch everything, but usually I don't need to see everything.