C 如何将输出重定向到/dev/null之外

C 如何将输出重定向到/dev/null之外,c,redirect,stdio,C,Redirect,Stdio,我有一个运行a命令的应用程序,如下所示: &/dev/null 我可以配置,但我无法控制。此命令生成的所有输出都将转到/dev/null。我希望输出在屏幕上可见或重定向到日志文件 我试图使用freopen()和相关函数重新打开另一个文件/dev/null,但无法使其工作 你还有别的想法吗?这可能吗 谢谢你抽出时间 PS:我在Linux上工作。可怕的黑客: 在二进制模式下使用文本编辑器打开应用程序,找到“/dev/null/”并将其替换为相同长度的字符串 e.g '~/tmp/log' 先做备

我有一个运行a命令的应用程序,如下所示:

&/dev/null

我可以配置
,但我无法控制
。此命令生成的所有输出都将转到
/dev/null
。我希望输出在屏幕上可见或重定向到日志文件

我试图使用
freopen()
和相关函数重新打开另一个文件
/dev/null
,但无法使其工作

你还有别的想法吗?这可能吗

谢谢你抽出时间

PS:我在Linux上工作。

可怕的黑客:

在二进制模式下使用文本编辑器打开应用程序,找到“/dev/null/”并将其替换为相同长度的字符串

e.g '~/tmp/log'
  • 先做备份
  • 小心
  • 小心
  • 我提到备份了吗

在命令末尾追加
#
,使其成为
#>&/dev/null
,从而注释掉不需要的部分。

您可以使用gdb对已经运行的进程执行此操作。请参见以下页面:

是否可以为该命令创建别名?如果是这样,请将其别名为另一个将输出转储到文件的命令。

编辑:这不是一个好主意,当然也不值得尝试,除非您知道这会破坏什么。它对我有用,也可能对你有用

#!/bin/bash
"$@" >> logfile
好的,这是一个非常糟糕的黑客行为,可能不值得去做。假设其他命令都不起作用,并且您无法访问二进制/应用程序(其中包含带有
/dev/null
)的命令),并且无法将输出重新定向到其他文件(通过替换
/dev/null

然后,您可以删除/dev/null(
$>rm/dev/null
),并在其位置创建自己的文件(最好使用软链接),所有数据都可以指向该位置。完成后,可以使用以下命令再次创建/dev/null:

$>mknod-m666/dev/null c13


非常清楚的是,这是一个糟糕的黑客行为,当然需要root权限才能工作。重新定向的文件很可能包含许多其他正在运行的应用程序/二进制文件中的数据,并将
/dev/null
用作接收器。

设备文件
/dev/tty
引用应用程序的控制终端-如果没有更改,那么这应该可以工作:

freopen("/dev/tty", "w", stdout);
freopen("/dev/tty", "w", stderr);
或者,您可以重新打开它们以指向日志文件:

freopen("/var/log/myapp.log", "a", stdout);
freopen("/var/log/myapp.err", "a", stderr);

您的应用程序可能正在运行shell并将其传递到该命令行

你需要让它运行你写的脚本。该脚本将把命令行中的
>/dev/null
替换为
>/your/log
,并使用修改后的命令行调用真正的shell

第一步是更改应用程序使用的shell。更改环境变量
SHELL
就足够了,也就是说,将应用程序作为

SHELL=/home/user/bin/myshell theApp
如果不起作用,请尝试暂时将
/bin/sh
链接到脚本

myshell
将调用原始shell,但在模式替换参数后:

#!/bin/bash
sh ${1+"${@/\>\/dev\/null/>>\/your\/log}"}

这方面的工作应该是可行的。

因为可以修改运行的命令,所以可以使用简单的shell脚本作为包装,将输出重定向到文件

#!/bin/bash
"$@" >> logfile

如果将其保存在路径中作为capture_output.sh,则可以将capture_output.sh添加到命令开头,将程序的输出附加到日志文件。

在perl中,如果您只想将
STDOUT
重定向到稍微有用的位置,可以执行以下操作:

open STDOUT, '>>', '/var/log/myscript.log';
open STDERR, '>>', '/var/log/myscript.err';

在脚本的开头,这将重定向到脚本的其余部分。

按照e-t172的答案,您能否将最后一个开关设置为(或附加到它):


它可能不完全重定向,但它允许在任何发送位置获取输出

strace-ewrite-p$PID

这并不是说克莱恩(展示了像:write(#,,)这样的行),而是很有效!(并且是单行的:D)你可能也不喜欢这样一个事实,即参数是缩写的。要控制该值,请使用-s参数设置显示的字符串的最大长度

它捕获所有流,因此您可能希望以某种方式对其进行过滤

您可以对其进行筛选:

strace-ewrite-p$PID 2>&1 | grep“write(1)”


仅显示描述符1调用。2>&1是将stderr重定向到stdout,因为strace默认情况下会写入stderr。

如果在将内容传递到/dev/null之前可以内联放置一些内容(不确定是否处理硬编码命令),则可以使用tee重定向到您选择的内容

Wikipedia中允许命令升级的示例:

echo "Body of file..." | sudo tee root_owned_file > /dev/null

这与Perl有什么关系?除非您可以更改脚本中的命令,否则我认为您运气不好。一旦它被重定向到null,您就无法将其取回,因为您可能与它共享的所有文件描述符(stdin、stdout、stderr)您可以控制命令,但不能重定向?如果是这样,我会说e-t172是正确的,或者至少与您将得到的一样正确:如果不是,请更新以澄清。我可以配置,但无法控制。
&/dev/null
将在不使用开关的情况下运行命令!:(我对我的问题进行了编辑,以使其更清楚。这个问题是否更适合ServerFault?它与C有什么关系?您是否考虑编写一个C程序来替换?一个可以捕获参数,然后调用命令,但将其输出重定向到日志文件的程序?说明:用文本e打开二进制可执行文件在二进制文件的乱七八糟的地方应该有“/dev/null”这就是您上面建议的替换内容。@lexu:我之前已经做过。用一个长度相等的空格字符串替换了/dev/null。这是可行的,但对于应用程序的每个版本,对可执行文件进行黑客攻击都是乏味的……我正在考虑编写一个这样做的程序