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

问题描述

我正在尝试将 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}。即使我手动添加 pid 也不起作用:

top "-pid "{45,23}

invalid option or Syntax: -pid 45

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

解决方法

我想我们可以想出更简洁的方法,但至少:

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

作为第一次尝试,在 Ubuntu/WSL 上的 fish 上似乎对我有用。这应该转化为:

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

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

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

这行得通,但很冗长。为简化起见,您想出了:

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

太棒了!老实说,我从未在 top (string split " " -- "-pid "(pgrep dart)) # MacOS top (string split " " -- "-p "(pgrep dart)) # Linux 中使用过 Cartesian Product,但这显然是您尝试进行大括号扩展时首先想要的。

使用该示例,我随后能够对其进行改进(至少在 Linux 上):

fish

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

,

您需要编写一个展开式,使展开式表达式的每个项在引用时产生 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}