问题标签 [process-substitution]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
274 浏览

bash - 用一点 awk 理解 bash 中的嵌套进程替换

我似乎无法弄清楚,这里发生了什么。我有 4 个版本的相同代码,唯一的区别是代码块/行的顺序。我最初的期望是重定向顺序没有任何区别,但它似乎并不正确。我还假设 >() 具有文件描述符机制的一些屏蔽属性,但没有...

请不要问我用它做什么,我也不需要替代解决方案,我想了解这段代码。或者我对过程替代的理解的信念将永远被打破......

元代码:

版本 1: 1 2 AB 3 CD

版本 2: 1 2 BA 3 DC

版本 3: 1 3 DC 2 BA

版本 4: 1 3 CD 2 AB

笔记:

我也尝试了 2 AB 和 2 BA,它们产生一致的输出,类似于版本 1。

awk:GNU awk 4.1.1,API:1.1(GNU MPFR 3.1.2-p3,GNU MP 6.0.0)

bash:GNU bash,版本 4.3.30(1)-release (x86_64-pc-linux-gnu)

版本 1,这会产生我期望的输出:

文件内容:

输出:

版本 2:

注意:与版本 1 相比,第 1 与第 2、第 3 与第 4 二级缩进行交换。

文件内容:

输出:

版本 3:

注意:与版本 2 相比,交换了第一级缩进代码块。

文件内容:

输出:

版本 4:

注意:与版本 3 相比,第 1 与第 2、第 3 与第 4 二级缩进行交换。

文件内容:

输出:

版本 2、3、4 中发生了什么?

0 投票
3 回答
373 浏览

linux - 将 tr 的结果作为 awk 中的第二个参数传递

我的命令:

问题是文件 2 包含\000字符并且 awk 将其视为二进制文件。

替换\000为空格字符:

解决二进制文件问题。

但是我的 file2 是一个 20GB 的文件。而且我不想tr单独做并将结果另存为另一个文件。我想将结果传递给trto awk

我试过了:

但结果是:

另一个问题是:我的内存或 awk 可以一次处理这么大的文件吗?我正在使用 12GB RAM 的 PC。

编辑

答案之一如我所料(感谢 Ed Morton)

然而,它比在 2 个步骤中执行相同操作要慢 2 倍 - 首先删除\000并保存它,然后awk用于搜索。我怎样才能加快速度?

编辑2

我的错。Ed Morton 解决方案实际上比在两个单独的命令中执行相同操作要快一点。

两个命令分别:08:37:053

两个命令管道:08:07:204

0 投票
1 回答
23 浏览

bash - Bash:日志记录会影响变量范围吗?

在我当前的项目中,我运行了一个循环,在执行期间定义了一个稍后需要的变量。一切都很好,直到我想用 tee 添加日志记录,这样我以后也可以在文件中检查日志。因为我想同时记录标准输出和标准错误,所以我申请|&了(的快捷方式2>&1 |)。但奇怪的是,变量的值会丢失。

输出:

同时我找到了一种更好的方法:当我切换到文件重定向进程替换的组合时,变量定义有效。

输出:

但我想了解,为什么:-)

  1. 为什么在第一个示例中值会丢失?
  2. 为什么它不会在第二次丢失?

你能告诉?

0 投票
1 回答
37 浏览

bash - “var=>(...) somecommand”是如何工作的?

在#2 中哪个部分首先执行?x=>(tr '[:lower:]' '[:upper:]')或 f <(echo 'hi there')。#2 是复合复合词还是单个命令?

0 投票
2 回答
616 浏览

bash - Bash:进程替换的范围是什么?

据我所知,进程替换 <(...) / >(...) 创建 fd

并将括号中的命令输出存储到生成的 fd 中。

因此,这两个命令是等价的

在这里,我的问题是,生成的文件描述符保留多长时间?

我读过这篇文章,但似乎我的理解是错误的。

如果进程替换扩展为函数的参数,在调用函数期间扩展为环境变量,或扩展为函数内的任何赋值,则进程替换将“保持打开”以供函数内的任何命令使用或其被调用者,直到设置它的函数返回。如果在被调用者中再次设置相同的变量,除非新变量是本地的,否则先前的进程替换将关闭,并且在被调用者返回时对调用者不可用。

本质上,扩展为函数内变量的进程替换保持打开状态,直到发生进程替换的函数返回——即使分配给由函数调用者设置的局部变量也是如此。动态范围并不能保护它们免于关闭。

阅读后我的最佳猜测是,创建的 fd 在使用之前不会关闭。

由此,我写了一个非常愚蠢的代码,如下所示

似乎新打开的 fd 在一行命令运行后就关闭了。

生成的fd维护多久,那么进程替换的范围是什么?

0 投票
1 回答
978 浏览

linux - bash 陷阱和进程替换

更新

我为我发布的答案使用了一个更好的测试用例。我在这里添加更新的测试用例,以防有人想进一步试验:

要获取 ascii-art 进程树(在单独的终端中):

---


---

我很难理解信号是如何在 bash 中传播的,以及哪个陷阱会处理它们。

我这里有 3 个例子。每个示例都使用 2 个变体进行了测试,即任一行都未注释。这些示例是由这个伪代码构建的:

我用这两个品种尝试了每个例子几次。我得到的结果很少,我发布了我找到的那种。

测试如下:

  1. 将脚本放在一个文件中
  2. 运行脚本文件
  3. Ctrl+C在脚本仍在运行时按下

注意:简单地将这些脚本复制粘贴到现有的 bash shell 中会产生与我从文件执行时得到的不同结果。为了限制这个问题的长度,我没有附上这些结果。

我的终极问题是:

我已经使用这种布局(复合语句 + 进程重定向)来运行一些代码,并过滤并保存输出。现在出于某种原因,我决定最好保护此设置不因中断而终止,但我发现很难做到这一点。我很快发现仅仅在脚本开头调用陷阱是不够的。

有什么方法可以使用 bash / trap 保护我的脚本免受信号的影响(并安装正确的关闭序列)?

信号往往会首先清除日志记录,所以我无法捕捉到主进程的垂死线......

(我在问题的末尾添加了更多的想法和分析。)

这将是一个很长的问题,但我认为发布我已经完成的工作将有助于了解正在发生的事情:

测试设置:

测试设置 1(1 只猫):

结果:

测试设置 2(2 只猫):

结果:

测试设置 3(2 只猫,无睡眠子外壳):

结果:

我的分析:

我添加所有 3 个测试用例的主要原因是有时我得到了一个SEGFAULT. 我对它进行了转储,但找不到它的来源。这似乎在某种程度上取决于主陷阱中的回声是否重定向到/dev/stderr变体 1)或不(变体 2)。

紧随其后Ctrl+C,通常"trapped 2"先激活,很少"end 2"。这表明(与我最初的看法相反),处理信号时不涉及进程层次结构。正在运行的进程(复合语句、2 个进程替换,在 h 和 h2 中是子shell、sleep进程、cat进程)并行运行,并且在传递信号时恰好正在运行的任何一个都将处理它。出于某种原因,这主要是 stderr 重定向的进程替换。我想这cat是主接收器,它没有安装信号处理程序,所以它就死了(这就是我尝试添加 2cat的原因,以便第二个可以保持子外壳运行)。

这就是重点,我没有真正的线索,会发生什么。(我什至不知道,如果我做到这一点......)

我认为,信号将从它传播cat到它的包含进程,进程替换 bash shell,它安装了一个信号处理程序,并打印"trapped 2".

现在,我原以为故事会到此结束,一枚戒指被伊熙尔杜摧毁,佛罗多留在家里……但没有。不知何故,它冒泡了,并设法杀死了sleep。即使有 2 cats,所以如果一个被破坏,子 shell 仍然保持活动状态。我发现 a 很可能SIGPIPE是杀死睡眠的原因,因为没有捕获它,我看到的行为与我在此处发布的行为不同。但有趣的是,似乎我需要trap SIGPIPE在每个位置,而不仅仅是在睡眠子外壳中,或者再次显示不同的行为。

我想,SIGPIPE信号到达sleep,杀死它,所以echo复合语句中只有一个 left ,它执行,并且那个子shell 完成了。标准输出重定向的进程替换也被杀死了,可能被另一个SIGPIPE被杀死的复合语句/函数外壳杀死?

更有趣的是,有时"trapped 1"根本没有显示。

奇怪的是我没有看到 50%"trapped 2"和 50% "trapped 1"

我可以做什么,我想要什么?

请记住,我的目标是有序关闭系统/服务/脚本。

1)首先,正如我所看到的,如果这里由/表示的“业务流程”没有自己的信号处理,那么再多的也无法挽救它们免于被杀死。sleepcattrap

2)信号处理程序不是继承的,每个子shell都必须有自己的陷阱系统。

3)没有什么能像进程组那样以公共方式处理信号,无论信号碰巧碰到哪个进程都会做它的事情,并且在那里被杀死的进程的结果可能会在进程树中传播得更远。

不过,我不清楚,如果一个进程不能处理一个信号,它会把它扔到它的包含外壳吗?或者是另一个信号,传递了什么?有些东西肯定会通过,否则不会触发信号处理程序。

在一个/我的理想世界中,atrap将保护安装它的 shell 中的任何东西不接收信号,因此sleep-s, cat-s 将被指定的清理功能关闭:杀死sleep,其余的将记录它的最后一个行,然后跟随- 而不是:所有日志记录都被清除,只有在那之后主进程才会最终被杀死......

我错过了一些微不足道的事情吗?设置 -o 魔法?继续添加更多的陷阱,直到它突然起作用?

问题:

之后信号如何真正传播Ctrl+C

从哪里来SEGFAULT

最重要的:

从记录开始,我可以保护这个结构不被信号夷为平地吗?或者我应该避免进程替换,并提出另一种类型的输出过滤/日志记录?

经测试:

GNU bash,版本 4.4.12(1)-release (x86_64-pc-linux-gnu)

进一步说明:

完成测试后,我发现了这些 QA-s,我认为这可能与我的案例有关,但我不知道,我究竟该如何使用它们:

如何使用运行前台子进程的 Bash 可靠地使用陷阱

子后台进程中的陷阱信号

不过,我尝试用 替换sleep 63while : ; do sleep 0.1; done结果如下:

测试设置 1:

测试设置 2:

测试设置 3:

所以,虽然这让我能够利用 2 cat-s,允许 2 Ctrl+C-s,但它总是让我SEGFAULT,仍然不知道它来自哪里。

0 投票
1 回答
762 浏览

bash - 如果调用或通过 tee,bash“wc -l”命令输出会有所不同

当我在 Bash 中发出两个等效命令时,我得到了不同的输出(来自“wc -l”命令),见下文:

我错过了什么?

这很奇怪,但是当我这样称呼它时,它会得到更奇怪的输出:

似乎命令异步运行并在不同的时间结束......或者它可能是什么?

0 投票
2 回答
107 浏览

linux - 进程替换 >(cmd) 没有正确输出

我正在尝试了解进程替换以及执行此操作时:

bash在下一个提示后打印数字并等待我按 Enter。

我正在使用bash 4.4.12,遇到同样的问题bash 4.3.48。没有问题,bash 4.3.30命令正确输出:

可能的问题是什么?

0 投票
1 回答
27 浏览

bash - 如何防止bash在进行多进程替换时返回相同的路径?

我想使用进程替换将一些字符串作为文件传递:

-arg可以接受文件路径或内联值。所以我为它创建了一个函数。

但问题是这个脚本输出

这是错误的,因为这两个标志接收到相同的内容。

是因为arg在新外壳中运行吗?

我想知道如何告诉 bash 不要对多个进程替换使用相同的路径?

我正在使用 bash 4.4.12

0 投票
1 回答
755 浏览

awk - 管道 awk 输出到另一个 awk 命令

我有一个制表符分隔的文件,例如:

我想得到第 6 列的总和:

第 7 列的总和:

然后将第 6 列的总和除以第 7 列的总和。

是否可以在一个命令中完全做到这一点?bash中的进程替换之类的东西?