Shell redirection vs explicit file handling code

2019-06-22 16:58发布

问题:

I am not a native english speaker so please excuse the awkward title of this question. I just not knew how to phrase it better.

I am on a FreeBSD box and I have a little filter tool written in C which reads a list of data via stdin and outputs a processed list via stdout. I invoke it somewhat like this: find . -type f | myfilter > /tmp/processed.txt.

Now I want to give my filter a little bit more exposure and publish it. Convention says that tools should allow something like this: find . -type f | myfilter -f - -o /tmp/processed.text

This would force me to write code that simply is not needed since the shell can do the job, therefore I tend to leave it out.

My question is: Do I miss some argument (other but convention) why the reading and writing of files should be done in my code an not delegated to shell redirection?

回答1:

There's absolutely nothing wrong with this. Your filter would have an interface similar to, say, c++filt.

You might consider file handling if you wanted to automatically choose an output file based on the name of an input file or if you wanted to special handling for processing multiple files in a single command.

If you don't want to do any either of these then there's nothing wrong with being a simple filter. Anyone can provide a set of simple shell wrappers to provide a cmd infile outfile syntax if they wish.



回答2:

That's a needlessly limiting interface. Accepting arguments from the command line is more flexible,

grep foo file | myfilter > /tmp/processed.text

and it doesn't preclude find from being used

find . -type f -exec myfilter {} + > /tmp/processed.text


回答3:

Actually to have the same effect as shell redirection you can do this:

freopen( "filename" , "wb" , stdout );

and so if you have used printf throughout your code, outputs will be redirected to the file. So you don't need to modify any of the code you've written before and easily adapt to the convention.



回答4:

It is nice to have as option run any command with filename argument. As in your example:

myfilter [-f ./infile] [-o ./outfile] #or
myfilter [-o outfile] [filename] #and (the best one)
myfilter [-f file] [-o file] #so, when the input and output are the same file - the filter should working correctly anyway

For the nice example check the sort command. Usually used as filer in pipes, but can do [-o output] and correctly handle the same input/output problem too...

And why it is good? For example, when want run the command from "C" by "fork/exec" and don't want start the shell for handling I/O. In this case is much easier (and faster) execve(.....) with arguments as start the cmd with a shell wrapper.



标签: c shell redirect