将文件输出重定向到标准输出

5

我有一个程序,只能通过-o选项将结果输出到文件中。这一次我需要将其输出到控制台,即stdout。以下是我的第一次尝试:

myprog -o /dev/stdout input_file

但是它显示:
/dev/ 不可写
我发现这个问题与我的类似,这里有一些相关信息,但是使用/dev/stdout显然需要一些额外的魔法。
问题:如何将文件输出重定向到 stdout
备注:最好使用没有任何专业软件的传统方法。

你能展示一下程序源代码吗?你在哪里做输出呢? - Samuel
@anubhava,感谢您的建议,但它也不起作用。 - Mark Karpov
1
@TomFenech,输出将保存到一个文件中,该文件的名称是通过将“.texi”扩展名替换为“.html”扩展名来生成的。它只是尝试猜测输出文件的名称。 - Mark Karpov
1
你可以尝试使用 myprog -o - input_file。通常情况下,- 被解释为标准输入/输出,但这取决于程序,而不是 shell 的一部分。 - Rambo Ramon
1
@Samuel,根据定义,此操作不需要root权限。我的意思是,即使普通用户也应该能够将输出重定向到屏幕。 - Mark Karpov
显示剩余6条评论
3个回答

5
许多工具根据其使用上下文将-解释为标准输入/输出。但这不是shell的一部分,因此取决于所使用的程序。
在您的情况下,以下内容可能会解决您的问题:
myprog -o - input_file

5

如果程序只能写入文件,那么您可以使用命名管道:

pipename=/tmp/mypipe.$$
mkfifo "$pipename"

./myprog -o "$pipename" &

while read line
do
    echo "output from myprog: $line"
done < "$pipename"

rm "$pipename"

首先我们创建一个管道,将其放置在/tmp目录下,以避免备份程序干扰。 $$是我们的PID,并使名称在运行时唯一。

我们在后台运行程序,它应该阻塞尝试向管道写入数据。有些程序使用一种称为“内存映射”的技术,在这种情况下,会失败,因为管道无法进行内存映射(好的程序会检查此情况)。

然后,我们像读取其他文件一样在脚本中读取管道。

最后,我们删除管道。


@Rambo Ramon:我应该指出,在我发布这篇文章之前,我没有看到您在scottgwald的帖子中的评论。当时我正在测试代码! - cdarke
没问题。使用命名管道得到完整答案很好,因为它比我的回答更通用。接受我的点赞 :) - Rambo Ramon
1
这可能会因为至少两个原因而失败。首先,如果myprog在打开目标文件之前删除了它;实际上似乎是这种情况,因为-o /dev/stdout返回错误/dev/ not writable。其次,如果myprog需要通过输出文件进行lseek()操作;这不是很常见,但绝对有可能发生。 - lcd047
@lcd047:同意。从根本上讲,我们确实需要更多关于程序的信息。如果使用了lseek(),那么接受的答案将不起作用(mmap()也是如此),但如果输出文件是“-”,则可能只是走了不同的分支。惊讶的是这不在程序的文档中。 :-) - cdarke

2
您可以使用cat命令查看由myprog编写的文件的内容。 myprog -o tmpfile input_file && cat tmpfile 这将产生所描述的效果,允许您将myprog的输出传输到后续的某些命令中,尽管它是一种与您设想的不同的方法。
如果myprog(也许更适当地称为notmyprog)的输出太大而无法写入磁盘,则此方法将不可行。
在同一行中清理临时文件并仍然在最后传输内容的解决方案如下: myprog -o tmpfile input_file && contents=`cat tmpfile` && rm tmpfile && echo "$contents" 它将文件的内容存储在一个变量中,以便在删除文件后可以访问该变量。请注意echo命令参数中的引号。这些引号很重要,以保留文件内容中的换行符。

这可能作为一种hack的方式。如果重定向不可能,这绝对是可行的方法,但我应该指出,它并没有回答问题。 - Mark Karpov
1
要将其视为答案,您至少应该提供删除临时文件的代码。除此之外,我建议使用命名管道而不是普通文件。 - Rambo Ramon
1
@scottgwald 关于“在大多数正常情况下并不重要”的评论,如果我们不知道 myprog 的具体功能,那么我们就无法确定什么是正常的。例如:如果整个程序的目的是输出文件太大而无法存储在磁盘上,并且我们正在重定向输出以便在写入时进行消耗,那么临时文件就没有用处。 - ckhan
1
@ckhan 理解了。cdarke的回答可能确实可以解决问题,我之前不熟悉命名管道。 - scottgwald
1
在你的辩护中,如果程序使用了内存映射文件,那么这是目前为止发布的唯一可行解决方案。显然,在这种情况下它不能使用mmap,因为接受的答案也不起作用(使用mmap创建和写入整个文件本来就很棘手)。 - cdarke
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接