当前位置: 首页 > news >正文

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

相关文章:

Linux Shell : Process Substitution

注&#xff1a;本文为 “Process Substitution” 相关文章合辑。 英文引文机翻&#xff0c;未校。 Process Substitution. 进程替换允许使用文件名引用进程的输入或输出。它采取以下形式 <(list)or >(list)进程 list 异步运行&#xff0c;其输入或输出显示为文件名。…...

JOGL 从入门到精通:开启 Java 3D 图形编程之旅

一、引言 Java 作为一门广泛应用的编程语言&#xff0c;在图形编程领域也有着强大的工具和库。JOGL&#xff08;Java OpenGL&#xff09;便是其中之一&#xff0c;它为 Java 开发者提供了访问 OpenGL&#xff08;Open Graphics Library&#xff09;功能的接口&#xff0c;使得…...

汽车网络安全基线安全研究报告

一、引言 随着汽车行业朝着智能网联方向飞速发展&#xff0c;汽车网络安全已成为保障用户安全和行业健康发展的关键要素。本报告将深入探讨汽车网络安全相关内容&#xff0c;以及国际、国内重要的汽车网络安全标准基线和相应防护措施等内容。 二、汽车网络安全的重要性 &…...

Eclipse 修改项目栏字体大小

1、菜单栏选择window->preference&#xff0c;然后选择General->Appearance->Colors and Fonts&#xff0c;在搜索栏输入"tree"&#xff0c;点击"Edit"修改字体。 2、修改字体&#xff0c;选择"四号字体"&#xff0c;点击"确定&qu…...

【PCIe 总线及设备入门学习专栏 5.1 -- PCIe 引脚 PRSNT 与热插拔】

文章目录 OverviewPRSNT 与热插拔PRSNT 硬件设计 Overview Spec 定义的热插拔是把一个PCIe卡&#xff08;设备&#xff09;从一个正在运行的背板或者系统中插入/或者移除。这个过程需要不影响系统的其他功能。插入的新的设备可以正确工作。 显然&#xff0c;这里面需要考虑的问…...

【YOLO】YOLOv5原理

概述 YOLOv5的主要架构 Backbone&#xff08;主干网络&#xff09;&#xff1a;负责提取输入图像的多层次特征 Neck&#xff08;颈部网络&#xff09;&#xff1a;进行特征融合和多尺度特征处理&#xff0c;通常包含FPN&#xff08;特征金字塔网络&#xff09;和PAN&#xff0…...

uniapp中wx.getFuzzyLocation报错如何解决

一、用wx.getLocation接口审核不通过 用uniapp开发小程序时难免需要获取当前地理位置。 代码如下&#xff1a; uni.getLocation({type: wgs84,success: function (res) {console.log(当前位置的经度&#xff1a; res.longitude);console.log(当前位置的纬度&#xff1a; r…...

opencv图像直方图

【欢迎关注编码小哥&#xff0c;学习更多实用的编程方法和技巧】 1、基本直方图计算 // 灰度图直方图 cv::Mat calculateGrayscaleHistogram(const cv::Mat& image) {cv::Mat histogram;int histSize 256; // 灰度级别float range[] {0, 256};const float* histRange …...

OpenCV计算机视觉 03 椒盐噪声的添加与常见的平滑处理方式(均值、方框、高斯、中值)

上一篇文章&#xff1a;OpenCV计算机视觉 02 图片修改 图像运算 边缘填充 阈值处理 目录 添加椒盐噪声 图像平滑常见处理方式 均值滤波 (blur) 方框滤波 (boxFilter) ​高斯滤波 (GaussianBlur) 中值滤波 (medianBlur) 添加椒盐噪声 def add_peppersalt_noise(image, n…...

【嵌入式C语言】内存分布

内存分布 内存分布图内存的属性&#xff1a;只读空间只读空间的特点编程注意事项 栈空间栈的工作原理栈的特点栈溢出与堆的区别 堆空间堆的特点内存分配函数内存泄漏总结 内存分布图 内存的属性&#xff1a; 在C语言中&#xff0c;内存的属性主要取决于它是如何分配的以及它在…...

【brainpan靶场渗透】

文章目录 一、基础信息 二、信息收集 三、反弹shell 四、提权 一、基础信息 Kali IP&#xff1a;192.168.20.146 靶机 IP&#xff1a;192.168.20.155 二、信息收集 似乎开放了9999&#xff0c;10000端口&#xff0c;访问页面没有太多内容&#xff0c;扫描一下目录 dirs…...

Java实现观察者模式

一、前言 观察者模式&#xff0c;又称为发布订阅模式&#xff0c;是一种行为设置模式&#xff0c;允许对象之间建立一对多的依赖关系&#xff0c;这样当一个对象状态改变时&#xff0c;它的所有依赖者&#xff08;观察者&#xff09;都会收到通知并自动更新。 二、具体实现 …...

通过百度api处理交通数据

通过百度api处理交通数据 1、读取excel获取道路数据 //道路名称Data EqualsAndHashCode public class RoadName {ExcelProperty("Name")private String name; }/*** 获取excel中的道路名称*/private static List<String> getRoadName() {// 定义文件路径&…...

探索CSDN博客数据:使用Python爬虫技术

探索CSDN博客数据&#xff1a;使用Python爬虫技术 在数字化的浪潮中&#xff0c;数据的获取与分析变得日益关键。CSDN作为中国领先的IT社区和服务平台&#xff0c;汇聚了海量的技术博客与文章&#xff0c;成为一座蕴藏丰富的数据宝库。本文将引领您穿梭于Python的requests和py…...

b站ip属地评论和主页不一样怎么回事

在浏览B站时&#xff0c;细心的用户可能会发现一个有趣的现象&#xff1a;某些用户的评论IP属地与主页显示的IP属地并不一致。这种差异引发了用户的好奇和猜测&#xff0c;究竟是什么原因导致了这种情况的发生呢&#xff1f;本文将对此进行深入解析&#xff0c;帮助大家揭开这一…...

如何查看服务器内存占用情况?

如何查看服务器的内存占用情况&#xff1f;你知道内存使用情况对服务器性能的重要性吗&#xff1f;内存是服务器运行的核心资源之一&#xff0c;了解内存的占用情况可以帮助你优化系统性能。 要查看服务器的内存占用情况&#xff0c;首先需要确定你使用的是哪种操作系统。不同…...

流架构的读书笔记(2)

流架构的读书笔记&#xff08;2&#xff09; 一、建模工具之一沃德利地图 推测技术的发展,交流和辩论思想的最有力的方法是沃德利地图 沃德利地图的制作步骤 1确定范围和用户需求 2确定满足用户需求所需的组件 3在一条范围从全新到被人们接受的演进轴上评估这些组成 部分的演…...

E6 中的 扩展运算符(Spread) 和 剩余运算符(Rest)

时间&#xff1a;2024.12.29 之前看到 Es6 中的 三点运算符&#xff0c;有如下的几种写法&#xff0c;有时候三点运算符放在左边&#xff0c;有时候三点运算符放在右边&#xff0c;老是混淆。今天记录下&#xff0c;加强理解。 先看一个问题 最近在看 《ECMAScript 6 入门》关于…...

Python的简单爬虫框架

爬虫为网络爬虫&#xff08;又称为网页蜘蛛&#xff0c;网络机器人&#xff0c;在FOAF社区中间&#xff0c;更经常的称为网页追逐者&#xff09;&#xff0c;是一种按照一定的规则&#xff0c;自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、…...

使用 uni-app 开发的微信小程序中,如何在从 B 页面回来时,重新拉取数据?

&#x1f468;&#x1f3fb;‍&#x1f4bb; 热爱摄影的程序员 &#x1f468;&#x1f3fb;‍&#x1f3a8; 喜欢编码的设计师 &#x1f9d5;&#x1f3fb; 擅长设计的剪辑师 &#x1f9d1;&#x1f3fb;‍&#x1f3eb; 一位高冷无情的全栈工程师 欢迎分享 / 收藏 / 赞 / 在看…...

Windows API Set:那些“只存在但不被使用“的DLL

API Set 是什么&#xff1f; 想象一下&#xff0c;Windows就像一个大型图书馆&#xff0c;而API Set就是这个图书馆的索引系统。但这个索引系统非常特别&#xff1a;它是直接内置在Windows加载器中的"虚拟目录"。 // 一个典型的API Set映射示例 api-ms-win-core-mem…...

黑神话悟空鼠标光标分享

效果图&#xff1a; 鼠标光标特点 这套鼠标光标的设计灵感来源于《黑神话&#xff1a;悟空》游戏中的角色和元素&#xff0c;具有以下特点&#xff1a; • 主题鲜明&#xff1a;光标设计紧扣游戏主题&#xff0c;采用了游戏中的元素&#xff0c;让玩家在使用电脑时也能感受到…...

编写一个简单的引导加载程序(bootloader)

编写一个简单的引导加载程序&#xff08;bootloader&#xff09;通常用于嵌入式系统或自定义操作系统。这里&#xff0c;我将为你提供一个基于x86架构的简单汇编语言 bootloader 示例。这个 bootloader 将会在启动时打印一条消息到屏幕上。 使用 NASM 汇编器来编写这个 bootlo…...

【Linux基础】进程(上) —— 概念、状态、优先级与环境变量

目录 一、进程的概念 1. 什么是进程 PCB进程控制块的理解 2. 查看进程的方式 ps ajx 指令 getpid系统调用 3. 另外一种查看进程的方式(了解) 4. 进程的常见调用 fork 创建子进程 现象说明 二、进程的状态 1. 操作系统层面的进程状态 ① 运行状态 ② 阻塞状态 ③…...

Rust: enum 和 i32 的区别和互换

在Rust编程语言中&#xff0c;enum&#xff08;枚举&#xff09;和i32是两种不同类型的数据结构&#xff0c;它们各自有不同的用途和特性。 i32 i32是一个32位的有符号整数类型。它用于存储整数值&#xff0c;范围从-2,147,483,648到2,147,483,647。i32是Rust中的基本数据类型…...

2024年终回顾

前言 很久没有更新博客&#xff0c;因为工作内容主要是内场开发&#xff0c;后来有点和互联网脱轨&#xff0c;断断续续上来看一下。这个总结应该也很简单&#xff0c;涉及以下的几个内容进行逐一说明 一、就业问题 这个问题可能很尖锐&#xff0c;从大环境来说&#xff0c;去…...

RGB、HSV颜色模型及MATLAB互换应用实例

一、前言 RGB和HSV模型是数字图像处理中颜色空间中的两种重要表示方式&#xff0c;RGB和HSV都是描述颜色的数学模型&#xff0c;可以用于表示和处理图像中的颜色信息。 RGB模型是一种基于光的颜色模型&#xff0c;由红&#xff08;Red&#xff09;、绿&#xff08;Green&#x…...

# 【超全面了解鸿蒙生命周期】-生命周期补充

【超全面了解鸿蒙生命周期】-生命周期补充 鸿蒙所有的生命周期函数梳理 文章目录 【超全面了解鸿蒙生命周期】-生命周期补充前言一、AbilityStage的生命周期二、ExtensionAbility卡片生命周期三、Web组件常用生命周期 前言 本文是继之前写的生命周期函数梳理的进一步补充&…...

黑神话悟空游戏鼠标光标使用教程与下载

效果图&#xff1a; 鼠标光标特点 这套鼠标光标的设计灵感来源于《黑神话&#xff1a;悟空》游戏中的角色和元素&#xff0c;具有以下特点&#xff1a; • 主题鲜明&#xff1a;光标设计紧扣游戏主题&#xff0c;采用了游戏中的元素&#xff0c;让玩家在使用电脑时也能感受到…...

【机器学习】梯度下降

文章目录 1. 梯度下降概念2. 梯度下降的技巧2.1 动态设置学习率2.2 Adagrad调整梯度2.3 随机梯度下降&#xff08;SGD&#xff09;2.4 特征缩放 3. 梯度下降理论基础 1. 梯度下降概念 梯度&#xff1a;Loss 对参数在某一点的偏微分&#xff0c;函数沿梯度的方向具有最大的变化…...