问题标签 [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.
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 中发生了什么?
linux - 将 tr 的结果作为 awk 中的第二个参数传递
我的命令:
问题是文件 2 包含\000
字符并且 awk 将其视为二进制文件。
替换\000
为空格字符:
解决二进制文件问题。
但是我的 file2 是一个 20GB 的文件。而且我不想tr
单独做并将结果另存为另一个文件。我想将结果传递给tr
to awk
。
我试过了:
但结果是:
另一个问题是:我的内存或 awk 可以一次处理这么大的文件吗?我正在使用 12GB RAM 的 PC。
编辑
答案之一如我所料(感谢 Ed Morton)
然而,它比在 2 个步骤中执行相同操作要慢 2 倍 - 首先删除\000
并保存它,然后awk
用于搜索。我怎样才能加快速度?
编辑2
我的错。Ed Morton 解决方案实际上比在两个单独的命令中执行相同操作要快一点。
两个命令分别:08:37:053
两个命令管道:08:07:204
bash - Bash:日志记录会影响变量范围吗?
在我当前的项目中,我运行了一个循环,在执行期间定义了一个稍后需要的变量。一切都很好,直到我想用 tee 添加日志记录,这样我以后也可以在文件中检查日志。因为我想同时记录标准输出和标准错误,所以我申请|&
了(的快捷方式2>&1 |
)。但奇怪的是,变量的值会丢失。
输出:
同时我找到了一种更好的方法:当我切换到文件重定向和进程替换的组合时,变量定义有效。
输出:
但我想了解,为什么:-)
- 为什么在第一个示例中值会丢失?
- 为什么它不会在第二次丢失?
你能告诉?
bash - “var=>(...) somecommand”是如何工作的?
在#2 中哪个部分首先执行?x=>(tr '[:lower:]' '[:upper:]')
或 f <(echo 'hi there')
。#2 是复合复合词还是单个命令?
bash - Bash:进程替换的范围是什么?
据我所知,进程替换 <(...) / >(...) 创建 fd
并将括号中的命令输出存储到生成的 fd 中。
因此,这两个命令是等价的
在这里,我的问题是,生成的文件描述符保留多长时间?
我读过这篇文章,但似乎我的理解是错误的。
如果进程替换扩展为函数的参数,在调用函数期间扩展为环境变量,或扩展为函数内的任何赋值,则进程替换将“保持打开”以供函数内的任何命令使用或其被调用者,直到设置它的函数返回。如果在被调用者中再次设置相同的变量,除非新变量是本地的,否则先前的进程替换将关闭,并且在被调用者返回时对调用者不可用。
本质上,扩展为函数内变量的进程替换保持打开状态,直到发生进程替换的函数返回——即使分配给由函数调用者设置的局部变量也是如此。动态范围并不能保护它们免于关闭。
阅读后我的最佳猜测是,创建的 fd 在使用之前不会关闭。
由此,我写了一个非常愚蠢的代码,如下所示
似乎新打开的 fd 在一行命令运行后就关闭了。
生成的fd维护多久,那么进程替换的范围是什么?
linux - bash 陷阱和进程替换
更新
我为我发布的答案使用了一个更好的测试用例。我在这里添加更新的测试用例,以防有人想进一步试验:
要获取 ascii-art 进程树(在单独的终端中):
---
---
我很难理解信号是如何在 bash 中传播的,以及哪个陷阱会处理它们。
我这里有 3 个例子。每个示例都使用 2 个变体进行了测试,即任一行都未注释。这些示例是由这个伪代码构建的:
我用这两个品种尝试了每个例子几次。我得到的结果很少,我发布了我找到的那种。
测试如下:
- 将脚本放在一个文件中
- 运行脚本文件
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 cat
s,所以如果一个被破坏,子 shell 仍然保持活动状态。我发现 a 很可能SIGPIPE
是杀死睡眠的原因,因为没有捕获它,我看到的行为与我在此处发布的行为不同。但有趣的是,似乎我需要trap
SIGPIPE
在每个位置,而不仅仅是在睡眠子外壳中,或者再次显示不同的行为。
我想,SIGPIPE
信号到达sleep
,杀死它,所以echo
复合语句中只有一个 left ,它执行,并且那个子shell 完成了。标准输出重定向的进程替换也被杀死了,可能被另一个SIGPIPE
被杀死的复合语句/函数外壳杀死?
更有趣的是,有时"trapped 1"
根本没有显示。
奇怪的是我没有看到 50%"trapped 2"
和 50% "trapped 1"
。
我可以做什么,我想要什么?
请记住,我的目标是有序关闭系统/服务/脚本。
1)首先,正如我所看到的,如果这里由/表示的“业务流程”没有自己的信号处理,那么再多的也无法挽救它们免于被杀死。sleep
cat
trap
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,我认为这可能与我的案例有关,但我不知道,我究竟该如何使用它们:
不过,我尝试用 替换sleep 63
,while : ; do sleep 0.1; done
结果如下:
测试设置 1:
测试设置 2:
测试设置 3:
所以,虽然这让我能够利用 2 cat
-s,允许 2 Ctrl+C
-s,但它总是让我SEGFAULT
,仍然不知道它来自哪里。
bash - 如果调用或通过 tee,bash“wc -l”命令输出会有所不同
当我在 Bash 中发出两个等效命令时,我得到了不同的输出(来自“wc -l”命令),见下文:
我错过了什么?
这很奇怪,但是当我这样称呼它时,它会得到更奇怪的输出:
似乎命令异步运行并在不同的时间结束......或者它可能是什么?
linux - 进程替换 >(cmd) 没有正确输出
我正在尝试了解进程替换以及执行此操作时:
bash
在下一个提示后打印数字并等待我按 Enter。
我正在使用bash 4.4.12
,遇到同样的问题bash 4.3.48
。没有问题,bash 4.3.30
命令正确输出:
可能的问题是什么?
bash - 如何防止bash在进行多进程替换时返回相同的路径?
我想使用进程替换将一些字符串作为文件传递:
-arg
可以接受文件路径或内联值。所以我为它创建了一个函数。
但问题是这个脚本输出
这是错误的,因为这两个标志接收到相同的内容。
是因为arg
在新外壳中运行吗?
我想知道如何告诉 bash 不要对多个进程替换使用相同的路径?
我正在使用 bash 4.4.12
awk - 管道 awk 输出到另一个 awk 命令
我有一个制表符分隔的文件,例如:
我想得到第 6 列的总和:
第 7 列的总和:
然后将第 6 列的总和除以第 7 列的总和。
是否可以在一个命令中完全做到这一点?bash中的进程替换之类的东西?