大括号扩展作为标志参数对

Brace expansion as flag argument pairs

我正在尝试结合使用 toppgrep 来过滤显示的进程。到目前为止我的工作是:

top -pid (pgrep dart)

这非常适合在 top 的交互式视图中显示单个进程。

然而,top的macos版本只有一种列出多个进程的方法,你必须一次又一次地重复-pid [process id]例如:

top -pid 354 -pid 236 -pid 287

我的第一个想法是我可以使用大括号扩展和命令替换来实现这一点,我尝试了:

top "-pid "{(pgrep dart)}

但我得到 invalid option or syntax: -pid {33978}。即使我手动添加 pids 它也不起作用:

top "-pid "{45, 23}

invalid option or syntax: -pid 45

有没有可能实现我想用鱼做的事情?即通过命令替换和大括号扩展的组合将标志插入命令?

我想我们可以想出更简洁的东西,但至少:

top (string split " " (printf " -p %s" (pgrep dart)))
作为我的第一次尝试,

fish 和 Ubuntu/WSL 上似乎对我有用。那应该 t运行 变成:

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

在 MacOS 上,但从评论来看,听起来 -pid 可能会传递给 printf(首先),然后是 string split,当然也不喜欢。在 WSL/Ubuntu 上,我 运行 遇到了那个问题,但能够通过在字符串的 开头 处添加 space 来解决它。但是,这似乎不适用于 Mac。您的解决方案确实是更规范的解决方案;使用 -- 来阻止这些命令按预期解释 -pid

因此,top (string split -n " " -- (printf -- "-pid %s " (pgrep dart))) 适用于 MacOS top,Linux/Ubuntu 所需的唯一更改是替换 -pid -p,如 top (string split -n " " -- (printf -- "-p %s " (pgrep dart))).

这有效,但非常冗长。为了简化,你想出了:

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

太棒了!老实说,我从未在 fish 中使用过 Cartesian Product,但这显然是您首先尝试进行大括号扩展的目的。

使用该示例,我可以将其改进(至少在 Linux 上)到:

top "-p "(pgrep dart)

但我感觉等效的 top "-pid "(pgrep dart) 不适用于 MacOS,因为 top "-pid "{45, 23} 也不适合您。出于某种原因,同样的构造 (top "-p "{1,11}) 对我有用。

您需要编写一个扩展,使扩展表达式的每个项在引用时产生 top 的有效参数。

"-pid "{45, 23} 乍一看,好像它应该是可行的:

> echo "-pid "{45, 23}   
-pid 45 -pid 23

所以,问题是什么?如果我们把原来的表达式定界再展开:

> echo ["-pid "{45, 23}]
[-pid 45] [-pid 23]

因此,您使用此扩展为 top 生成的命令行将被解析为:

top "-pid 45" "-pid 23"

相反,请注意以下几点:

> p={45,23} echo [{-pid,$p}]
[-pid] [45] [-pid] [23]

FiSH 做对的事情有多少,做错的事情也有多少,所以无缘无故,以下是不可行的:

> echo [{-pid,{45,23}}]
[-pid] [45] [23]

因此,将您的进程 ID 列表存储在一个数组中,然后使用大括号展开:

p=(pgrep dart) top {-pid,$p}