6

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

<command> <switches> >& /dev/null

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

我尝试使用freopen()和相关功能重新打开/dev/null到另一个文件,但无法使其正常工作。

你还有其他建议吗?这可能吗?

谢谢你的时间。

PS:我在Linux上工作。

4

12 回答 12

8

可怕的黑客:

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

e.g '~/tmp/log'
  • 先备份
  • 小心点
  • 非常小心
  • 我有提到备份吗?
于 2010-03-24T12:34:46.080 回答
4

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

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

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

于 2010-03-24T13:46:07.370 回答
3

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

于 2010-03-24T12:37:44.453 回答
2

您的应用程序可能正在运行一个 shell 并将该命令行传递给它。

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

第一步是更改应用程序使用的外壳。更改环境变量SHELL就足够了,即,将您的应用程序运行为

SHELL=/home/user/bin/myshell theApp

如果这不起作用,请尝试暂时链接/bin/sh到您的脚本。

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

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

这些方面的东西应该起作用。

于 2010-03-24T13:14:37.947 回答
1

您可以使用 gdb 对已运行的进程执行此操作。请参阅以下页面:http ://etbe.coker.com.au/2008/02/27/redirecting-output-from-a-running-process/

于 2010-03-24T12:38:34.667 回答
1

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

于 2010-03-24T12:45:12.470 回答
1

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

好的,这是一个非常糟糕的 hack,可能不值得做。假设其他命令都不起作用,并且您根本无法访问二进制/应用程序(其中包含带有 的命令/dev/null),并且您无法将输出重定向到其他文件(通过替换/dev/null)。

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

$> mknod -m 666 /dev/null c 1 3

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

于 2010-03-24T12:46:04.700 回答
1

设备文件/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);
于 2010-03-24T12:50:05.413 回答
1

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

strace -ewrite -p $PID

它不是那么干净(显示如下行: write(#,) ),但有效!(并且是单行 :D )您可能也不喜欢这样一个事实,即参数是缩写的。要控制使用 -s 参数设置显示的字符串的最大长度。

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

你可以过滤它:

strace -ewrite -p $PID 2>&1 | grep "write(1"

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

于 2010-04-27T21:23:23.037 回答
0

在 perl 中,如果您只想重定向STDOUT到更有用的东西,您可以执行以下操作:

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

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

于 2010-03-24T14:10:54.380 回答
0

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

; echo 
于 2010-03-24T14:28:37.007 回答
0

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

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

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

http://en.wikipedia.org/wiki/Tee_(command)

于 2010-05-16T03:24:23.717 回答