Search code examples
fish

Brace expansion as flag argument pairs


I'm trying to use top in conjunction with pgrep to filter the processes that are being shown. What I have working so far is:

top -pid (pgrep dart)

Which works great for getting a single process to show in top's interactive view.

However, the macos version of top only has one way of listing multiple processes, you have to just repeat -pid [process id] again and again eg:

top -pid 354 -pid 236 -pid 287

My first thought was that I could use brace expansion and command substitution to achieve this, and I tried:

top "-pid "{(pgrep dart)}

But I get invalid option or syntax: -pid {33978}. Even when I manually add in pids it doesn't work:

top "-pid "{45, 23}

invalid option or syntax: -pid 45

Is it possible to achieve what I'm trying to do with fish? i.e insert flags into a command via a combination of command substitution and brace expansion?


Solution

  • I'm thinking we can come up with something more concise, but at least:

    top (string split " " (printf " -p %s" (pgrep dart)))
    

    seems to work for me on fish on Ubuntu/WSL as a first attempt. That should translate to:

    top (string split " " (printf " -pid %s" (pgrep dart)))
    

    on MacOS, but from the comments, it sounds like the -pid may be getting passed to printf (first), and then string split, which neither like, of course. On WSL/Ubuntu, I ran into that problem, but was able to resolve it by adding the space at the beginning of the string. However, that appears to not be working for Mac. Your solution is really the more canonical one; use -- to stop those commands from interpreting the -pid as intended for them.

    So, top (string split -n " " -- (printf -- "-pid %s " (pgrep dart))) works for MacOS top, and the only change needed for Linux/Ubuntu is to replace the -pid with -p, as in top (string split -n " " -- (printf -- "-p %s " (pgrep dart))).

    Which works, but is quite verbose. To simplify, you came up with:

    top (string split " " -- "-pid "(pgrep dart)) # MacOS
    top (string split " " -- "-p "(pgrep dart)) # Linux
    

    Brilliant! I've honestly never used Cartesian Product in fish, but that's clearly what you were going for in the first place with your brace-expansion attempts.

    Using that example, I was then able to improve it (at least on Linux) to:

    top "-p "(pgrep dart)
    

    But I have a feeling that the equivalent top "-pid "(pgrep dart) isn't going to work on MacOS, since top "-pid "{45, 23} didn't work for you either. That same construct (top "-p "{1,11}) works for me, for some reason.