对具有重定向的stdin和stdout使用相同的文件 [英] Using the same file for stdin and stdout with redirection

查看:88
本文介绍了对具有重定向的stdin和stdout使用相同的文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个应用程序,其作用类似于过滤器:它从文件(stdin)读取输入,进行处理,然后将输出写入另一个文件(stdout).在应用程序开始写入输出文件之前,已完全读取输入文件.

I'm writing a application that acts like a filter: it reads input from a file (stdin), processes, and write output to another file (stdout). The input file is completely read before the application starts to write the output file.

因为我使用的是stdin和stdout,所以我可以这样运行:

Since I'm using stdin and stdout, I can run is like this:

$ ./myprog <file1.txt >file2.txt

它工作正常,但是如果我尝试使用相同的文件作为输入和输出(即:从文件读取并写入相同的文件),则如下所示:

It works fine, but if I try to use the same file as input and output (that is: read from a file, and write to the same file), like this:

$ ./myprog <file.txt >file.txt

它会在程序有机会读取它之前清除file.txt.

it cleans file.txt before the program has the chance to read it.

有什么办法可以在Unix的命令行中执行类似的操作吗?

Is there any way I can do something like this in a command line in Unix?

推荐答案

在执行程序之前,外壳程序会处理输出文件,因为它正在准备输出文件句柄.在外壳程序通过单个外壳程序命令行替换文件之前,无法使程序读取输入.

The shell is what clobbers your output file, as it's preparing the output filehandles before executing your program. There's no way to make your program read the input before the shell clobbers the file in a single shell command line.

在读取文件之前,您需要使用两个命令,即移动或复制文件:

You need to use two commands, either moving or copying the file before reading it:

mv file.txt filecopy.txt
./myprog < filecopy.txt > file.txt

否则输出到副本,然后替换原始副本:

Or else outputting to a copy and then replacing the original:

./myprog < file.txt > filecopy.txt
mv filecopy.txt file.txt

如果无法执行此操作,则需要将文件名传递给程序,程序将以读取/写入模式打开文件,并在内部处理所有I/O.

If you can't do that, then you need to pass the filename to your program, which opens the file in read/write mode, and handles all the I/O internally.

./myprog file.txt                 # reads and writes according to its own rules

这篇关于对具有重定向的stdin和stdout使用相同的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆