每个壳中的键入管道

2021-06-17 10:34:58

PowerShell和Nushell将Unix管道超出原始文本的原始流或键入数据。是否有可能保留传统的贝壳般的bash,仍然可以获得键入的管道?

我认为这是可能的,我' m现在惊讶的noone似乎已经完成了它。这是一个相当详细的设计,了解如何做到。我尚未展示它。 RFC。

让' s从一个名为键入的命令开始。您可以在Pipelinelike中使用它:

键入的类型是将命令的类型发现到左侧,并启动,同时传送它返回它们的命令类型。然后它检查类型是否匹配,并运行该命令,将该命令传送到它。管道是单向的,所以它看起来可能hardto发现类型的权利,但我'会解释怎么能说是donein一分钟。

现在假设Foo生成JSON,栏滤波器结构化的无数类型的数据,而BAZ消耗CSV和漂亮打印一张表。然后,BARWILL被告知其输入应该是JSON,它的输出应该是CSV。如果杆没'吨支持JSON,类型化foo和类型化barwould都失败,类型错误。

写作"键入的"面前一切都很烦人。但它可以制作ashell别名和#34; t"它还可以使用键入的程序包装:

或程序可以导入使用键入的库,因此在键入的流水线中使用的支持。我' ll解释了一种方式以后的图书馆在后来,一旦更多细节很清楚。

如果其中一个命令实际上没有键入,则管道中的另一个是将其具有作为输入或输出的原始文本流。有时会导致类型错误(yay,我喜欢类型错误!),但在其他案例可以做一些有用的东西。

找到|酒吧| BAZ#类型错误,BAR预期JSON或CSVFO |酒吧|较少#少显示CSV

那么键入如何发现左右命令的类型?那个努力部分。它必须首先查找到Itsleft和右侧的PID。没有真正的好方法来做这一点,但在Linux中,ITCan完成:查看到什么/ proc / self / fd / 0和/ proc / self / fd / 1链接,其中包含管道的唯一标识符。然后看看其他工业和#39; FD / 0和FD / 1找到匹配的管道标识符。 (它' osopossible在osx上做到这一点,我相信。我不知道bsds。)

搜索所有进程将有点昂贵(约15毫秒乘坐平均进程数),但是有一个很好的优化:Shell将及时开始靠近进程,因此Thepid可能在附近。所以看看以前的PID,而下一个PID,扇子向外。此外,检查IntaTty以检测管道的开头和结束,并避免在这些情况下扫描所有流程。

要指示它将运行的命令的类型,键入的简单opensa文件,扩展名为#34; .typed"该文件可以位于空中,可以是已存在的文件,也可以根据需要创建(例如,/运行)。一旦它在Apipe的另一端发现PID,键入的首先看起来/ proc / $ pid / cmdline看它' salso运行键入。如果是,它看起来是它的打开文件handlesto找到第一个" .typed"文件。它可能需要等待它的文件Handleto被打开,这就是为什么它需要验证PID的键入。

还需要有一种方法来学习将运行的Commandit的类型。阅读/usr/share/typed/$$ .Typed是一种方法。它可以在命令行中指定,这对于包装脚本很有用:

并且键入将类型信息传送到它运行的命令。这方面的命令像栏一样可以知道其输入应该是什么格式,以及用作输出的格式。这可能会使用环境varialbles来完成,例如input_type = json和output_type = csv

除了类型的语法之外,我认为这一切的所有需求和#39;类型检查工作。 我应该不能试图思考袖口。 我在上面的例子中使用了Haskell ADT语法,但是Don' tthink那个'必然是正确的选择。 最后,这里' s如何制作一个库,该库允许在键入的管道中使用程序本地支持。 它'有点棘手,因为它必须运行键入,因为键入的检查/ proc / $ pid / cmdline,如上所述。 因此,检查环境变量。 未设置但设置它和exec键入,将其传递给程序的路径,它将重新执行。 这应该在程序做任何其他事情之前完成。