Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redirecting of stdout in bash vs writing to file in c with fprintf (speed)

I am wondering which option is basically quicker.

What interests me the most is the mechanism of redirection. I suspect the file is opened at the start of the program ./program > file and is closed at the end. Hence every time a program outputs something it should be just written to a file, as simple as it sounds. Is it so? Then I guess both options should be comparable when it comes to speed.

Or maybe it is more complicated process since the operating system has to perform more operations?

like image 334
thim Avatar asked Apr 17 '15 13:04

thim


People also ask

How would you redirect output from stdout to a file?

Redirecting stdout and stderr to a file: The I/O streams can be redirected by putting the n> operator in use, where n is the file descriptor number. For redirecting stdout, we use “1>” and for stderr, “2>” is added as an operator.

What does the 1 stdout redirect do in bash?

1 Redirecting Input. Redirection of input causes the file whose name results from the expansion of word to be opened for reading on file descriptor n , or the standard input (file descriptor 0) if n is not specified.

Can you redirect stdout and stderr to the same file?

When saving the program's output to a file, it is quite common to redirect stderr to stdout so that you can have everything in a single file. > file redirect the stdout to file , and 2>&1 redirect the stderr to the current location of stdout . The order of redirection is important.


2 Answers

There is no much difference between that options (except making file as a strict option reduces flexibility of your program). To compare both approaches, let's check, what stays behind a magical entity FILE*:

So in both cases we have a FILE* object, a file descriptor fd - a gateway to an OS kernel and in-kernel infrastructure that provides access to files or user terminals, which should (unless libc has some special initializer for stdout or kernel specially handles files with fd = 1).

How does bash redirection work in compare with fopen()?

When bash redirects file:

fork()                      // new process is created
fd = open("file", ...)      // open new file
close(1)                    // get rid of fd=1 pointing to /dev/pts device
dup2(fd, 1)                 // make fd=1 point to opened file
close(fd)                   // get rid of redundant fd
execve("a")                 // now "a" will have file as its stdout
// in a
stdout = fdopen(1, ...)

When you open file on your own:

fork()                           // new process is created
execve("a")                      // now "a" will have file as its stdout
stdout = fdopen(1, ...)         
my_file = fopen("file", ...)     
    fd = open("file", ...)
    my_file = fdopen(fd, ...)

So as you can see, the main bash difference is twiddling with file descriptors.

like image 185
myaut Avatar answered Sep 21 '22 09:09

myaut


Yes, you are right. The speed will be identical. The only difference in the two cases is which program opens and closes the file. When you redirect it using shell, it is the shell that opens the file and makes the handle available as stdout to the program. When the program opens the file, well, the program opens the file. After that, the handle is a file handle in both the cases, so there should be absolutely no difference in speed.

As a side remark, the program which writes to stdout can be used in more general ways. You can for example say

./program | ssh remotehost bash -c "cat > file"

which will cause the output of the program to be written to file on remotehost. Of course in this case there is no comparison like one you are making in the question.

like image 23
Abhay Avatar answered Sep 22 '22 09:09

Abhay