hylepo hylepo - 1 year ago 54
Linux Question

How can GNU time utility ignores pipe symbol and takes all what left in command line as one execve argument?

Linux, if I run

time tar -c stock_file | lz4 > stock_file.lz4
, actually it makes something like
time (tar -c stock_file | lz4 > stock_file.lz4)
, but if I write one little program:

#include <stdio.h>

int main (int argc, char **argv)
for (int i = 1; i < argc; ++i)
printf("The %dth user parameter, %s\n", i, argv[1]);
return 0;

Then I build it to
and run it:

shell@kernel: ~> ./pretending_time well | cat
The 1th user parameter, well

Well well, the parameter is
well | cat
, then I have the check the source code of
to figure it out how
well | cat
as one parameter

git clone git://git.savannah.gnu.org/time.git

Only one file source code, feels good

main (argc, argv)
int argc;
char **argv;
const char **command_line;


Feels not good, compile it carefully

error: ‘argc’ was not declared in this scope
error: ‘argv’ was not declared in this scope
error: initializer expression list treated as compound expression
error: expected ‘,’ or ‘;’ before ‘int’
error: expected unqualified-id before ‘{’ token

What is

main (argc, argv)
int argc;
char **argv;

I have never seen it before, and I can't compile it, is this allowed in c-lang? is this the way how
takes the pipe symbol
in the parameter?

Answer Source

The reason time behaves differently than other (external) programs is because time is not actually a program, it's a bash builtin. For comparison, consider the following examples: with the bash builtin we get

$ time sleep 1 | sleep 2
real   0m2.003s

whereas with the external time

$ /usr/bin/time sleep 1 | sleep 2
0.00user 0.00system 0:01.00elapsed 0%CPU (0avgtext+0avgdata 7488maxresident)k

So as you can see, in first case time times both sleep operations, whereas in the second case it only times the first sleep. In general, it is impossible to build a version of time as an external program that works like the first example. The reason is that whenever bash see the pipe character, it will execute the stuff on the left and the stuff on the right independently. So the left side will never have a chance to see what the right side command looks like. On the other hand, with the builtin time, bash can recognize it and treat it specially.