【问题标题】:Unix : How to modify and redirect stdout of all running processesUnix:如何修改和重定向所有正在运行的进程的标准输出
【发布时间】:2016-04-27 13:15:59
【问题描述】:

我想修改和重定向所有正在运行的进程的输出。我知道如果我知道进程的名称,我可以做这样的事情

process 2>&1 >/dev/null 

这会将 stderr 和 stdout 重定向到 dev/null。首先,在将标准输出发送到 dev/null 或其他任何地方之前,我将如何修改它?一种可能的解决方案是

process 2>&1 | awk '{print "$SOME_ENV_VAR|" $0;}' > dev/null

这是正确的方法吗?是否可以忍受 stdout 和 stderr 都被重定向?

  1. 如果我不想重定向到 dev/null,而是想打印到控制台怎么办?

  2. 更大的问题是,如何为每个正在运行的进程执行此操作?我需要在我不知道正在运行的进程名称的 linux 机器中执行此操作。这可行吗?

我对 shell 脚本还很陌生,所以请原谅我这些问题是微不足道的。

【问题讨论】:

  • 首先,您应该说明您使用的是哪种外壳。对于 linux,您很可能正在使用 bash。然后,running processes 建议您尝试在启动进程之后修改 I/O 分配 - 这是不可能的(至少在没有特殊内核支持的情况下)。但是,您的示例建议您在进程开始时指定 I/O。最后,您应该详细说明您想要实现的目标。 sh(因此也是 bash)在 stin/stdout/stderr 的进程如何相互连接方面非常强大。
  • 谢谢,我刚刚注意到awk '{print "$SOME_ENV_VAR|" $0;}' 没有覆盖环境变量。如何在 awk 中使用环境变量?
  • 这不是awk 的属性,而是您在awk 脚本参数中使用单引号(') 的结果。它会插值,例如你确实使用过:awk '{print '"$SOME_ENV_VAR|"' $0;}'。但是,这只会在发送 /dev/null 之前将 $SOME_ENV_VAR 的值添加到 process 的每一行。
  • 或者,您可以使用-v 切换到awk 来分配变量。在您的情况下,例如:awk -v var="$SOME_ENV_VAR" '{ print var "|" $0;}'
  • 太棒了!谢谢你的作品

标签: linux unix redirect awk


【解决方案1】:

从讨论中发现你并不是真的打算 将已经运行的进程的输出重定向到其他地方。但是您似乎正在尝试修改您正在启动的进程的输出。

使用 bash(似乎是您正在使用的),您可以使用 [FD]>TARGET resp。 [FD]<SOURCE 用于指定进程的 I/O 通道。 FD 是可选的,是一个文件描述符编号。忽略它意味着< 上的0 (=stdin) 和> 上的1 (=stdout)。 (2 是众所周知的标准错误文件描述符)。 TARGETSOURCE 我是文件系统对象(例如文件、设备、命名管道、unix 域套接字)或 &FD 其中FD 再次是文件描述符编号并指示要使用的(打开的)文件描述符。

您将使用它,例如,通过写入 2>&1 将错误输出发送到 stdout 将要发送的位置。

如果您现在想要对进程的输出进行后处理(实际上这是 shell 术语中的管道,因为它可以是任何复杂的(shell)语句,由多个命令和 I/O 重定向组成。) 您将使用管道:(A | B)。
这基本上将进程 A 的标准输出与进程 B 的标准输入连接起来。

为了操作输出,您可以使用任何其他 unix 命令或程序。最常见的是sed(用于应用基于正则表达式的替换)或awk。其他人可能还会推荐perlpython

在您的情况下,您打算在每一行前面加上某个环境变量给出的前缀。

使用awk你可以这样写:

awk '{ print "'"$SOME_ENV_VAR"'|" $0;}'

或将外部值作为 awk 变量传入:

awk -v var="$SOME_ENV_VAR" '{ print var "|" $0;}'

更进一步:

使用 bash 进行输出重定向非常强大。例如,您可以将 stdout 传递给一个管道并将 sterr 传递给另一个。例如:

(((echo hallo; echo ERROR >&2) | awk '{ print "stdout|" $0; }' >&4) 2>&1|  awk '{ print "stderr: " $0;}' ) 4>&1   

这将通过单独的 awk 实例处理 stdout 和 sterr 并将(组合的)输出发送到 shell 的正常 stdout。

【讨论】:

  • 太棒了!谢谢。 4在这里是什么意思? 1 是标准输出,2 是标准错误,我认为 3 是调试。对吗?
  • 文件描述符是一个整数 (>=0)。实际上这是进程特定的打开文件表的索引。最大值取决于系统。使用 ulimit -n 获取系统的当前最大值。我只是故意在这里选择了“4”。唯一的要求是:不同于已经开放的标准描述符值 (0,1,2)。 4>&1 正在打开此描述符。 >&4 正在使用它。 (schell 正在为这些发出dup 系统调用。)0,1,2 由 shell 管理,因此“众所周知”其他任何事情都取决于程序和用户。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 2011-01-06
  • 2011-01-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多