我有一个func
可以生成表格输出或 json 输出的 tion。我知道处理这个问题的常规方法是使用这样的参数:
$ func -j | jq .firstField
$ func -t | awk '{print $1}'
我想“向前看”并根据管道中的下一阶段推断输出类型。理想的用法很简单:
$ func | jq .firstField
$ func | awk '{print $1}'
我想象在 func 的某个地方,我会检查管道中下一阶段的第 0 个参数,看看它是否包含一个j
. 如果是这样,我会生成 json,否则会生成表格。
bash 允许这样的巫术吗?如果是这样,怎么做?
没有与管道关联的正式元数据或查询 API,除了可以通过流程工具从流程树中抢救出来的内容,或者
/proc
如果存在的话,可以从类型文件系统中挖掘出来。父 shell 将(可能)在内存中的某个地方拥有完整的管道,并且将知道所涉及的各种子进程,尽管同样没有 API 可以让任意cat
的(毫无意义,除了作为示例)管道cat | cat | cat | ...
知道cat
它在那个管道,因此它的同行是谁。更有用,因为有了独特的标志,人类将更容易分辨哪个是哪个;
pstree(1)
例如在另一个终端可能会显示但这不会告诉我们
cat -e
管道到cat -n
,只告诉我们猫袋都属于父 shell 35276 的进程组。如果您所在的系统有
/proc
或命令检查 pid 的哪些管道或描述符连接到什么,您可能能够弄清楚什么连接到进程所属的进程组中的什么。例如,在 linux 上lsof
运行类似的 cat 管道时,可以链接cat -e
和命令,因为它们共享管道 14301040:cat -n
因此,虽然这些信息可能可用,但可能需要大量挖掘和使用不可移植的工具进行重建才能弄清楚。
父 shell 可能会提供一种在输入管道后重写管道的方法,尽管 ZSH 挂钩函数
preexec
似乎没有提供任何重写要运行的命令的方法。(这样的功能可能类似于 LISP 宏让程序员重新编写代码的方式。)父 shell 也可能提供某种 API 子进程可用于检查管道......但是这些类型的添加需要编写进入外壳。然而,可以构建一个复杂的管道:
在这种情况下,您
func
要么无法找到awk
并做出(可能)错误的反应,要么您的流程管道搜索功能需要递归遍历下一个管道元素的所有命令,在这种情况下,它awk
可能func
与飞。或者你可能忘记你设置了这个行为并且awk
可能被错误地修改,这可能会导致难以发现的错误......我已经能够做到这一点,至少在 Linux 上是这样。这是一个演示它的脚本:https ://gist.github.com/MatrixManAtYrService/790a4a058bc841b0ceb2eb0263fb5d88
示例用法: