Linux Shell : Process Substitution

注:本文为 “Process Substitution” 相关文章合辑。

英文引文机翻,未校。


Process Substitution.

进程替换允许使用文件名引用进程的输入或输出。它采取以下形式

<(list)

or

>(list)

进程 list 异步运行,其输入或输出显示为文件名。该文件名作为扩展结果作为参数传递给当前命令。如果使用 >(list) 形式,写入文件将为 list 提供输入。如果使用 <(list) 形式,则应读取作为参数传递的文件以获得 list 的输出。请注意,< 或 > 与左括号之间不得出现空格,否则该结构将被解释为重定向。支持命名管道 (FIFO) 或/dev/fd 命名打开文件的方法。

如果可用,进程替换与参数和变量扩展、命令替换和算术扩展同时执行。


Bash process substitution Bash 进程替换

Posted on 2012-02-27 by Tom Ryder

For tools like diff that work with multiple files as parameters, it can be useful to work with not just files on the filesystem, but also potentially with the output of arbitrary commands. Say, for example, you wanted to compare the output of ps and ps -e with diff -u. An obvious way to do this is to write files to compare the output:
对于像 diff 这样使用多个文件作为参数的工具,不仅使用文件系统上的文件,而且可能使用任意命令的输出也很有用。例如,假设您想将 psps -e 的输出与 diff -u 进行比较。一个明显的方法是编写文件来比较输出:

$ ps > ps.out
$ ps -e > pse.out
$ diff -u ps.out pse.out

This works just fine, but Bash provides a shortcut in the form of process substitution, allowing you to treat the standard output of commands as files. This is done with the <() and >() operators. In our case, we want to direct the standard output of two commands into place as files:
这工作得很好,但 Bash 以进程替换的形式提供了一个快捷方式,允许您将命令的标准输出视为文件。这是通过 <()>() 运算符完成的。在我们的例子中,我们希望将两个命令的标准输出作为文件定向到位:

$ diff -u <(ps) <(ps -e)

This is functionally equivalent, except it’s a little tidier because it doesn’t leave files lying around. This is also very handy for elegantly comparing files across servers, using ssh:
这在功能上是等效的,只是它更整洁一些,因为它不会留下文件。这对于使用 ssh 优雅地比较不同服务器的文件也非常方便:

$ diff -u .bashrc <(ssh remote cat .bashrc)

Conversely, you can also use the >() operator to direct from a filename context to the standard input of a command. This is handy for setting up in-place filters for things like logs. In the following example, I’m making a call to rsync, specifying that it should make a log of its actions in log.txt, but filter it through grep -vF .tmp first to remove anything matching the fixed string .tmp:
相反,您也可以使用 >() 运算符从文件名上下文定向到命令的标准输入。这对于为日志等内容设置就地过滤器非常方便。在下面的示例中,我调用了 rsync,指定它应该记录 log.txt 中的操作,但首先通过 grep -vF .tmp 对其进行过滤,以删除与固定字符串 .tmp 匹配的任何内容:

$ rsync -arv --log-file=>(grep -vF .tmp >log.txt) src/ host::dst/

Combined with tee this syntax is a way of simulating multiple filters for a stdout stream, transforming output from a command in as many ways as you see fit:
tee 结合使用时,此语法是一种模拟 stdout 流的多个过滤器的方法,以您认为合适的多种方式转换命令的输出:

$ ps -ef | tee >(awk '$1=="tom"' >toms-procs.txt) \
        >(awk '$1=="root"' >roots-procs.txt) \
        >(awk '$1!="httpd"' >not-apache-procs.txt) \
        >(awk 'NR>1{print $1}' >pids-only.txt)

In general, the idea is that wherever on the command line you could specify a file to be read from or written to, you can instead use this syntax to make an implicit named pipe for the text stream.
通常,这个想法是,在命令行的任何地方,你可以指定要读取或写入的文件,你可以改用此语法为文本流创建一个隐式命名管道。

Thanks to Reddit user Rhomboid for pointing out an incorrect assertion about this syntax necessarily abstracting mkfifo calls, which I’ve since removed.
感谢 Reddit 用户 Rhomboid 指出关于此语法必须抽象 mkfifo 调用的错误断言,此后我将其删除。


Linux Shell 技巧: 进程替代 (Process Substitution)

ZMonster’s 2015-01-03

What is process substitution?

“Process Substitution”,我将之翻译为"进程替代",不知道有没有更相应的专业中文翻译,姑且先用着好了。它允许用将命令的输出结果当作"文件"来使用——这句话的意思是这样的,假设有一个工具,它原本接受的参数应该是一个指代某个具体文档的"文件名",使用"进程替代"后,可以用其他命令的输出来作为文件的内容,让这个工具去处理。

说得比较绕,先看看 Wikipedia 上的解释:

In computing, process substitution is a form of inter-process communication that allows the input or output of a command to appear as a file. The command is substituted in-line, where a file name would normally occur, by the command shell. This allows programs that normally only accept files to directly read from or write to another program.

Process substitution on Linux

在Linux上,通过下面的形式使用 process substituion:

<(<some command> <args>)

下面用一个实际的例子来说明它的使用。

以我的工作为例,对于一个测试集,在进行完 Speaker Diarization 后,会根据标注文件(即用作参照的标准结果)计算它的错误率,而 Speaker Diarization 的错误率由三部分组成:

  • Missed speech
  • False alarm speech
  • Speaker error

读者不必对这些词的具体含义去深究,只要知道是一个错误率的统计,同时总体错误由三个成分组成就行了。

在计算了错误率之后,会将统计结果记录在一个文件中,在这个文件中,每一行都一个音频的测试结果,形式如下:

1.wav Miss = 2.9 False = 3.4 Speaker = 1.0 Total = 7.3

现在有两个这样的文件,是对同一批测试集进行了两次测试后得到的结果,第一个文件 2015-05-31-der.log 的内容如下:

1.wav Miss = 2.9 False = 3.4 Speaker = 1.0 Total = 7.3
2.wav Miss = 1.0 False = 2.5 Speaker = 0.0 Total = 3.5
3.wav Miss = 2.7 False = 1.1 Speaker = 0.1 Total = 3.9

第二个文件 2015-06-22-der.log 的内容如下:

2.wav Miss = 0.5 False = 2.2 Speaker = 0.9 Total = 3.6
1.wav Miss = 2.8 False = 0.0 Speaker = 0.0 Total = 2.8
3.wav Miss = 2.4 False = 1.3 Speaker = 0.4 Total = 4.1

(注: 以上数据纯属杜撰,与我目前工作中的实际错误率情况没有任何关系)

我需要根据这两个文件,得到每个音频在两次测试中各个成分的对比情况,希望输出的每一行是这样的:

1.wav Miss = 2.9 False = 3.4 Speaker = 1.0 Total = 7.3 | Miss = 2.8 False = 0.0 Speaker = 0.0 Total = 2.8

比较容易想到需要根据文件名进行 sort ,然后使用 paste 把两个文件拼接起来,那么很自然地可以这样写:

sort -k1,1 2015-05-31-der.log > 2015-05-31-der-sorted.log
sort -k1,1 2015-06-22-der.log | cut -d ' ' -f 2- > 2015-06-22-der-sorted.log
paste -d '|' 2015-05-31-der-sorted.log 2015-06-22-der-sorted.log
rm *-sorted.log

使用进程替代的话,我可以用一行就搞定,而且不需要生成临时文件:

paste -d '|' <(sort -k1,1 2015-05-31-der.log) <(sort -k1,1 2015-06-22-der.log | cut -d ' ' -f 2-)

另外一个例子,就是使用 diff 比较两个文件内容的时候,而且关心的是某个文件中某个记录在另外一个文件中有没有,不希望受次序影响时—— diff 是按行来进行文件内容对比的。还是来假设一个场景吧。

假设我和我的一个朋友各自出去购物,完了回来想比较一下购买东西的区别:我买的东西里面哪些他没有买,他买的哪些我没有买。

我的购物清单是 shopping-list-1.txt ,内容如下:

苹果
上衣
毛巾
耳机
无线键盘

我朋友的购物清单是 shopping-list-2.txt ,内容如下:

耳机
苹果
无线键盘
科幻小说
五号电池
体重秤
移动电源

那么相比不用进程替代的传统办法,使用进程替代的办法会简单很多,一行搞定:

$ diff <(sort shopping-list-1.txt) <(sort shopping-list-2.txt)

结果如下:

diff结果

$ diff <(sort shopping-list-1.txt) <(sort shopping-list-2.txt)
2c2
< 毛巾
---
> 科幻小说
4c4
< 上衣
> 体重秤
5a6,7
> 五号电池
> 移动电源

可以看到,我买了而我朋友没买的东西是:

毛巾
上衣

我朋友买了而我没买的东西是:

科幻小说
体重秤
五号电池
移动电源

Some more

实际上,进程替代也不是什么很新奇的东西,Wikipedia 上说,它是进程间通信的一种方式,事实上也确实是这样。在 Linux 上使用进程替代的时候,系统会创建一个临时的文件描述符,然后将用以替代的进程的输出和这个文件描述符关联起来,这个可以通过以下命令来验证:

echo <(sort shopping-list-1.txt)

不出意外,应该会看到这样的输出:

/dev/fd/63

"fd"就是文件描述父 (File Description) 的缩写,但去 /dev/fd/ 下面找这个文件描述符,却会发现找不到,那是因为这个文件描述符是临时的,在传给"echo"命令后就被释放了。

此外,进程替代并不能和文件完全等价,这一点要切记。进程替代所建立的"对象",是不能进行写入和随机读取操作的。不能写入的话应该很好理解,因为如果进行写操作,将会写到那个临时的文件描述符里面去,而这个临时文件描述符会被迅速地释放掉,而且由于创建的这个"文件"——姑且这么称呼,不是一个 regular file (与之相对的是 special file),如果在写入时有严格的检查,甚至连写入都会被拒绝;有时候需要对文件进行随机读取,比如 C 语言里的 fseek() 函数的操作,这样的操作将不能在进程替代产生的临时对象上正常运作。

总的来说,我个人是很喜欢这个功能的,减少了处理数据时不少的工作量。

That’s it!


via:

  • Bash process substitution Posted on 2012-02-27 by Tom Ryder.
    https://sanctum.geek.nz/arabesque/bash-process-substitution/

  • Linux Shell技巧: 进程替代(Process Substitution) · ZMonster’s Blog 2015/01/03
    https://www.zmonster.me/2015/01/03/process-substitution.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/944513.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

十二月第五周python

第一个程序&#xff0c;熟悉转换器&#xff0c;把加法计算器变成exe# // 1,制作加法计算器&#xff0c; # 输入两个数字得到相加结果并输出aint(input("输入数字&#xff1a;"))#int()是把输入的内容转换成整数&#xff0c; bint(input("输入数字&#xff1a;&…

【视觉惯性SLAM:十一、ORB-SLAM2:跟踪线程】

跟踪线程是ORB-SLAM2的核心之一&#xff0c;其主要任务是实时跟踪相机的位姿变化和场景的变化&#xff0c;以维持地图的更新和相机轨迹的估计。ORB-SLAM2的跟踪线程通过多种方式&#xff08;参考关键帧跟踪、恒速模型跟踪、重定位跟踪、局部地图跟踪&#xff09;处理跟踪丢失、…

在字节5年被优化,太难了。。。

先简单说下&#xff0c;涵哥是某不知名 985 的本硕&#xff0c;17 年毕业加入字节&#xff0c;以“人员优化”的名义无情被裁员&#xff0c;之后跳槽到了有赞&#xff0c;一直从事软件测试的工作。还差几个月也7年了吧&#xff0c;算是在这行的资深划水员。7年的时间也让涵哥从…

阿里云-将旧服务器数据与配置完全迁移至新服务器

文章目录 一&#xff1a;创建镜像二&#xff1a;将创建好的镜像复制到新服务器所在的目标地域&#xff08;如果新服务器与镜像在同一地域就不用进行这一操作&#xff09;三&#xff1a;将镜像配置到新服务器上四&#xff1a;导出安全组&#xff08;如果新服务器与旧服务器使用同…

Spark SQL DML语句

【图书介绍】《Spark SQL大数据分析快速上手》-CSDN博客 《Spark SQL大数据分析快速上手》【摘要 书评 试读】- 京东图书 Spark本地模式安装_spark3.2.2本地模式安装-CSDN博客 DML&#xff08;Data Manipulation Language&#xff0c;数据操作语言&#xff09;操作主要用来对…

路过石岩浪心古村

周末常去的七彩城堡儿童乐园附近经常有老房子&#xff0c;没想到老房子最多的地方还是浪心古村。而且越看越有历史。 见到一座写着《序西书室》的房子&#xff0c;我最开始以为是一个古代的学校。但是查了百度更加不知道什么意思了哈。‌“序西书室”‌是指《文心雕龙》中的一个…

运行Zr.Admin项目(后端)

1.下载Zr.Admin代码压缩包 https://codeload.github.com/izhaorui/Zr.Admin.NET/zip/refs/heads/main 2.打开项目 我这里装的是VS2022社区版 进入根目录&#xff0c;双击ZRAdmin.sln打开项目 3.安装.net7运行时 我当时下载的代码版本是.net7的 点击安装 点击安装&#xff0…

Wordly Wise 3000 国际背单词01 介绍 + 测词汇量

&#x1f4da; Wordly Wise 3000 国际背单词01 介绍 测词汇量 &#x1f31f; 大家好&#xff01;我们正式启动背Wordly Wise 3000单词&#xff0c;旨在利用国际资源和科学的学练方法&#xff0c;帮助大家更得效地坚持学练单词。我们将通过图文和Video等多种形式与大家分享经验…

HarmonyOS Next 实现登录注册页面(ARKTS) 并使用Springboot作为后端提供接口

1. HarmonyOS next ArkTS ArkTS围绕应用开发在 TypeScript &#xff08;简称TS&#xff09;生态基础上做了进一步扩展&#xff0c;继承了TS的所有特性&#xff0c;是TS的超集 ArkTS在TS的基础上扩展了struct和很多的装饰器以达到描述UI和状态管理的目的 以下代码是一个基于…

3.微服务灰度发布落地实践(组件灰度增强)

文章目录 前言调用链示图dubbo服务之间的的调链cloud 服务之间的调用链 网关servlet容器: 标签续传1.定义插件2.实现灰度增强拦截 线程池: 标签续传1.拦截Runnable或Callable,接口增强实现标签续传;Callable 插件定义Runnable 插件定义拦载Callabl或Runnable构造(可共用)拦载ru…

不修改内核镜像的情况下,使用内核模块实现“及时”的调度时间片超时事件上报

一、背景 之前的博客 不修改内核镜像的情况下&#xff0c;使用内核模块实现高效监控调度时延-CSDN博客 里&#xff0c;我们讲了不修改内核镜像高效监控每次的调度时延的方法。这篇博客里&#xff0c;我们对于调度时间片也做这么一个不修改内核镜像的改进。关于调度时间片过长的…

机器视觉中的单线程、多线程与跨线程:原理与应用解析

在机器视觉应用中&#xff0c;程序的运行效率直接影响到系统的实时性和稳定性。随着任务复杂度的提高&#xff0c;单线程处理往往无法满足高性能需求&#xff0c;多线程技术因此被广泛应用。此外&#xff0c;跨线程操作&#xff08;如在多线程中更新界面或共享资源&#xff09;…

喜报 | 擎创科技入围上海市优秀信创解决方案

近日&#xff0c;由上海市经信委组织的“2024年上海市优秀信创解决方案”征集遴选活动圆满落幕&#xff0c;擎创科技凭借实践经验优秀的《擎创夏洛克智能预警与应急处置解决方案》成功入选“2024年上海市优秀信创解决方案”名单。 为激发创新活力&#xff0c;发挥标杆作用&…

linux-21 目录管理(一)mkdir命令,创建空目录

对linux而言&#xff0c;对一个系统管理来讲&#xff0c;最关键的还是文件管理。那所以我们接下来就来看看如何实现文件管理。当然&#xff0c;在文件管理之前&#xff0c;我们说过&#xff0c;文件通常都放在目录下&#xff0c;对吧&#xff1f;所以先了解目录&#xff0c;可能…

【Redis】 数据淘汰策略

面试官询问缓存过多而内存有限时内存被占满的处理办法&#xff0c;引出 Redis 数据淘汰策略。 数据淘汰策略与数据过期策略不同&#xff0c; 过期策略针对设置过期时间的 key 删除&#xff0c; 淘汰策略是在内存不够时按规则删除内存数据。 八种数据淘汰策略介绍 no evision&…

一网多平面

“一网多平面”是一种网络架构概念&#xff0c;具体指的是在一张物理网络之上&#xff0c;逻辑划分出“1N”个平面。以下是对“一网多平面”的详细解释&#xff1a; 定义与构成 01一网多平面 指的是在统一的物理网络基础设施上&#xff0c;通过逻辑划分形成多个独立的网络平面…

小程序配置文件 —— 12 全局配置 - pages配置

全局配置 - pages配置 在根目录下的 app.json 文件中有一个 pages 字段&#xff0c;这里我们介绍一下 pages 字段的具体用法&#xff1b; pages 字段&#xff1a;用来指定小程序由哪些页面组成&#xff0c;用来让小程序知道由哪些页面组成以及页面定义在哪个目录&#xff0c;…

MyBatis如何处理延迟加载?

大家好&#xff0c;我是锋哥。今天分享关于【MyBatis如何处理延迟加载&#xff1f;】面试题。希望对大家有帮助&#xff1b; MyBatis如何处理延迟加载&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 MyBatis 支持 延迟加载&#xff08;Lazy Loading&am…

Quartz任务调度框架实现任务动态执行

说明&#xff1a;之前使用Quartz&#xff0c;都是写好Job&#xff0c;指定一个时间点&#xff0c;到点执行。最近有个需求&#xff0c;需要根据前端用户设置的时间点去执行&#xff0c;也就是说任务执行的时间点是动态变化的。本文介绍如何用Quartz任务调度框架实现任务动态执行…

vue3使用video-player实现视频播放(可拖动视频窗口、调整大小)

1.安装video-player npm install video.js videojs-player/vue --save在main.js中配置全局引入 // 导入视频播放组件 import VueVideoPlayer from videojs-player/vue import video.js/dist/video-js.cssconst app createApp(App) // 视频播放组件 app.use(VueVideoPlayer)2…