仅通过过滤器传输 STDERR

2024-10-18 09:00:00
admin
原创
180
摘要:问题描述:在 bash 中,有没有办法先将 STDERR 通过过滤器传输,然后再将其与 STDOUT 统一?也就是说,我想要STDOUT ────────────────┐ ├─────> terminal/file/whatever STDERR ── [...

问题描述:

在 bash 中,有没有办法先将 STDERR 通过过滤器传输,然后再将其与 STDOUT 统一?也就是说,我想要

STDOUT ────────────────┐
                       ├─────> terminal/file/whatever
STDERR ── [ filter ] ──┘

而不是

STDOUT ────┐
           ├────[ filter ]───> terminal/file/whatever
STDERR ────┘

解决方案 1:

总结:

$ cmd 2> >(stderr-filter >&2)

例子:

% cat /non-existant 2> >(tr o X >&2)
cat: /nXn-existant: NX such file Xr directXry
%

这在 bash 和 zsh 中都有效。Bash 现在几乎无处不在,但是,如果你真的需要一个(非常复杂的)POSIX 解决方案sh,那么请参阅此处。


解释

到目前为止,最简单的方法是通过进程替换重定向 STDERR :

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

>(list)

进程列表异步运行,其输入或输出以文件名的形式出现。

因此,通过进程替换您可以获得一个文件名。

就像你可以做的那样:

$ cmd 2> filename

你可以做

$ cmd 2> >(filter >&2)

>&2将的STDOUTfilter重定向回原始 STDERR。

解决方案 2:

下面是一个示例,模仿了如何在 bash 中交换文件描述符。 a.out 的输出如下,没有 'STDXXX: ' 前缀。

STDERR: stderr output
STDOUT: more regular

./a.out 3>&1 1>&2 2>&3 3>&- | sed 's/e/E/g'
more regular
stdErr output

引用上面的链接:

  1. 首先将 stdout 保存为 &3 (&1 被复制到 3)

  2. 接下来将 stdout 发送到 stderr (&2 被复制到 1)

  3. 将 stderr 发送到 &3 (stdout)(&3 被复制到 2)

  4. 关闭 &3(&- 被欺骗为 3)

解决方案 3:

TL;DR:(bash 和 zsh)

$ cmd 2> >(stderr-filter >&2)

例子:

% cat /non-existant 2> >(tr o X >&2)
cat: /nXn-existant: NX such file Xr directXry
%

StackExchange 网络上的许多答案都具有以下形式:

cat /non-existant 3>&1 1>&2 2>&3 3>&- | sed 's/e/E/g'

这有一个内置假设:文件描述符 3 没有用于其他用途。

相反,使用命名的文件描述符,并将{ba,z}sh分配下一个可用的文件描述符 >= 10:

cat /non-existant {tmp}>&1 1>&2 2>&$tmp {tmp}>&- | sed 's/e/E/g'

请注意,POSIX 不支持命名文件描述符sh

上述的另一个问题是,如果不将 STDOUT 和 STDERR 再次交换回其原始值,则无法将该命令通过管道传输到其他命令。

为了允许在 POSIX 中进行向前管道传输sh(并且仍然假设 FD 3 不是它的使用),它变得复杂了:

(cmd 2>&1 >&3 3>&- | stderr-filter >&2 3>&-) 3>&1

因此,鉴于这个假设和复杂的语法,您最好使用上面 TL;DR 中显示的更简单的bash/语法,并在此处进行解释。zsh


实际演示,仅 grepping stderr:

$ ls -l . noexistABC noexistXYZ
ls: cannot access 'noexistABC': No such file or directory
ls: cannot access 'noexistXYZ': No such file or directory
.:
total 4
-rw-rw-r-- 1 frank frank    0 Aug 19 12:26 bar.txt
-rw-rw-r-- 1 frank frank    0 Aug 19 12:26 foo.txt
drwxrwxr-x 2 frank frank 4096 Aug 19 12:26 someFolder


$ ( ls -l . noexistABC noexistXYZ 2>&1 >&3 3>&- | grep ABC >&2 3>&-) 3>&1
.:
ls: cannot access 'noexistABC': No such file or directory
total 4
-rw-rw-r-- 1 frank frank    0 Aug 19 12:26 bar.txt
-rw-rw-r-- 1 frank frank    0 Aug 19 12:26 foo.txt
drwxrwxr-x 2 frank frank 4096 Aug 19 12:26 someFolder

解决方案 4:

简单使用进程替换似乎可以允许从中stderr单独过滤stdout

:; ( echo out ; echo err >&2 ) 2> >( sed s/^/e:/ >&2 )
out
e:err

请注意,它会不断地出现stderr,我们可以通过将整个内容包装在另一个子 shell 中并重定向到文件来看到它,stderr`stdoutstdouto`e

( ( echo out ; echo err >&2 ) 2> >( sed s/^/e:/ >&2 ) ) 1>o 2>e

解决方案 5:

我发现使用 bash 进程替换更容易记住和使用,因为它几乎逐字反映了最初的意图。例如:

$ cat ./p
echo stdout
echo stderr >&2
$ ./p 2> >(sed -e 's/s/S/') | sed 's/t/T/'
sTdout
STderr

仅使用第一个 sed 命令作为 stderr 上的过滤器,并使用第二个 sed 命令修改连接的输出。

请注意,2> 后面的空格是正确解析命令所必需的。

解决方案 6:

高级 Bash 脚本指南此页面的最后一部分是“仅将 stderr 重定向到管道”。

仅将 stderr 重定向到管道。

exec 3>&1                              # Save current "value" of stdout.
ls -l 2>&1 >&3 3>&- | grep bad 3>&-    # Close fd 3 for 'grep' (but not 'ls').
#              ^^^^   ^^^^
exec 3>&-                              # Now close it for the remainder of the script.

谢谢,SC

这也许就是你想要的。如果不是,ABSG 的其他部分应该能够帮助你,这非常好。

解决方案 7:

看一下命名管道:

$ mkfifo err
$ cmd1 2>err |cat - err |cmd2
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1120  
  IPD(Integrated Product Development,集成产品开发)流程是一种广泛应用于高科技和制造业的产品开发方法论。它通过跨职能团队的紧密协作,将产品开发周期缩短,同时提高产品质量和市场成功率。在IPD流程中,CDCP(Concept Decision Checkpoint,概念决策检查点)是一个关...
IPD培训课程   75  
  研发IPD(集成产品开发)流程作为一种系统化的产品开发方法,已经在许多行业中得到广泛应用。它不仅能够提升产品开发的效率和质量,还能够通过优化流程和资源分配,显著提高客户满意度。客户满意度是企业长期成功的关键因素之一,而IPD流程通过其独特的结构和机制,能够确保产品从概念到市场交付的每个环节都围绕客户需求展开。本文将深入...
IPD流程   66  
  IPD(Integrated Product Development,集成产品开发)流程是一种以跨职能团队协作为核心的产品开发方法,旨在通过优化资源分配、提高沟通效率以及减少返工,从而缩短项目周期并提升产品质量。随着企业对产品上市速度的要求越来越高,IPD流程的应用价值愈发凸显。通过整合产品开发过程中的各个环节,IPD...
IPD项目管理咨询   76  
  跨部门沟通是企业运营中不可或缺的一环,尤其在复杂的产品开发过程中,不同部门之间的协作效率直接影响项目的成败。集成产品开发(IPD)作为一种系统化的项目管理方法,旨在通过优化流程和增强团队协作来提升产品开发的效率和质量。然而,跨部门沟通的复杂性往往成为IPD实施中的一大挑战。部门之间的目标差异、信息不对称以及沟通渠道不畅...
IPD是什么意思   70  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用