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 这样使用多个文件作为参数的工具,不仅使用文件系统上的文件,而且可能使用任意命令的输出也很有用。例如,假设您想将 ps 和 ps -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
注:本文为 “Process Substitution” 相关文章合辑。 英文引文机翻,未校。 Process Substitution. 进程替换允许使用文件名引用进程的输入或输出。它采取以下形式 <(list)or >(list)进程 list 异步运行,其输入或输出显示为文件名。…...
JOGL 从入门到精通:开启 Java 3D 图形编程之旅
一、引言 Java 作为一门广泛应用的编程语言,在图形编程领域也有着强大的工具和库。JOGL(Java OpenGL)便是其中之一,它为 Java 开发者提供了访问 OpenGL(Open Graphics Library)功能的接口,使得…...
汽车网络安全基线安全研究报告
一、引言 随着汽车行业朝着智能网联方向飞速发展,汽车网络安全已成为保障用户安全和行业健康发展的关键要素。本报告将深入探讨汽车网络安全相关内容,以及国际、国内重要的汽车网络安全标准基线和相应防护措施等内容。 二、汽车网络安全的重要性 &…...
Eclipse 修改项目栏字体大小
1、菜单栏选择window->preference,然后选择General->Appearance->Colors and Fonts,在搜索栏输入"tree",点击"Edit"修改字体。 2、修改字体,选择"四号字体",点击"确定&qu…...
【PCIe 总线及设备入门学习专栏 5.1 -- PCIe 引脚 PRSNT 与热插拔】
文章目录 OverviewPRSNT 与热插拔PRSNT 硬件设计 Overview Spec 定义的热插拔是把一个PCIe卡(设备)从一个正在运行的背板或者系统中插入/或者移除。这个过程需要不影响系统的其他功能。插入的新的设备可以正确工作。 显然,这里面需要考虑的问…...
【YOLO】YOLOv5原理
概述 YOLOv5的主要架构 Backbone(主干网络):负责提取输入图像的多层次特征 Neck(颈部网络):进行特征融合和多尺度特征处理,通常包含FPN(特征金字塔网络)和PAN࿰…...
uniapp中wx.getFuzzyLocation报错如何解决
一、用wx.getLocation接口审核不通过 用uniapp开发小程序时难免需要获取当前地理位置。 代码如下: uni.getLocation({type: wgs84,success: function (res) {console.log(当前位置的经度: res.longitude);console.log(当前位置的纬度: r…...
opencv图像直方图
【欢迎关注编码小哥,学习更多实用的编程方法和技巧】 1、基本直方图计算 // 灰度图直方图 cv::Mat calculateGrayscaleHistogram(const cv::Mat& image) {cv::Mat histogram;int histSize 256; // 灰度级别float range[] {0, 256};const float* histRange …...
OpenCV计算机视觉 03 椒盐噪声的添加与常见的平滑处理方式(均值、方框、高斯、中值)
上一篇文章:OpenCV计算机视觉 02 图片修改 图像运算 边缘填充 阈值处理 目录 添加椒盐噪声 图像平滑常见处理方式 均值滤波 (blur) 方框滤波 (boxFilter) 高斯滤波 (GaussianBlur) 中值滤波 (medianBlur) 添加椒盐噪声 def add_peppersalt_noise(image, n…...
【嵌入式C语言】内存分布
内存分布 内存分布图内存的属性:只读空间只读空间的特点编程注意事项 栈空间栈的工作原理栈的特点栈溢出与堆的区别 堆空间堆的特点内存分配函数内存泄漏总结 内存分布图 内存的属性: 在C语言中,内存的属性主要取决于它是如何分配的以及它在…...
【brainpan靶场渗透】
文章目录 一、基础信息 二、信息收集 三、反弹shell 四、提权 一、基础信息 Kali IP:192.168.20.146 靶机 IP:192.168.20.155 二、信息收集 似乎开放了9999,10000端口,访问页面没有太多内容,扫描一下目录 dirs…...
Java实现观察者模式
一、前言 观察者模式,又称为发布订阅模式,是一种行为设置模式,允许对象之间建立一对多的依赖关系,这样当一个对象状态改变时,它的所有依赖者(观察者)都会收到通知并自动更新。 二、具体实现 …...
通过百度api处理交通数据
通过百度api处理交通数据 1、读取excel获取道路数据 //道路名称Data EqualsAndHashCode public class RoadName {ExcelProperty("Name")private String name; }/*** 获取excel中的道路名称*/private static List<String> getRoadName() {// 定义文件路径&…...
探索CSDN博客数据:使用Python爬虫技术
探索CSDN博客数据:使用Python爬虫技术 在数字化的浪潮中,数据的获取与分析变得日益关键。CSDN作为中国领先的IT社区和服务平台,汇聚了海量的技术博客与文章,成为一座蕴藏丰富的数据宝库。本文将引领您穿梭于Python的requests和py…...
b站ip属地评论和主页不一样怎么回事
在浏览B站时,细心的用户可能会发现一个有趣的现象:某些用户的评论IP属地与主页显示的IP属地并不一致。这种差异引发了用户的好奇和猜测,究竟是什么原因导致了这种情况的发生呢?本文将对此进行深入解析,帮助大家揭开这一…...
如何查看服务器内存占用情况?
如何查看服务器的内存占用情况?你知道内存使用情况对服务器性能的重要性吗?内存是服务器运行的核心资源之一,了解内存的占用情况可以帮助你优化系统性能。 要查看服务器的内存占用情况,首先需要确定你使用的是哪种操作系统。不同…...
流架构的读书笔记(2)
流架构的读书笔记(2) 一、建模工具之一沃德利地图 推测技术的发展,交流和辩论思想的最有力的方法是沃德利地图 沃德利地图的制作步骤 1确定范围和用户需求 2确定满足用户需求所需的组件 3在一条范围从全新到被人们接受的演进轴上评估这些组成 部分的演…...
E6 中的 扩展运算符(Spread) 和 剩余运算符(Rest)
时间:2024.12.29 之前看到 Es6 中的 三点运算符,有如下的几种写法,有时候三点运算符放在左边,有时候三点运算符放在右边,老是混淆。今天记录下,加强理解。 先看一个问题 最近在看 《ECMAScript 6 入门》关于…...
Python的简单爬虫框架
爬虫为网络爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、…...
使用 uni-app 开发的微信小程序中,如何在从 B 页面回来时,重新拉取数据?
👨🏻💻 热爱摄影的程序员 👨🏻🎨 喜欢编码的设计师 🧕🏻 擅长设计的剪辑师 🧑🏻🏫 一位高冷无情的全栈工程师 欢迎分享 / 收藏 / 赞 / 在看…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...
