GNU time 实用程序如何忽略管道符号并将命令行中剩下的所有内容作为一个 execve 参数?

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

Linux,如果我 运行 time tar -c stock_file | lz4 > stock_file.lz4,实际上它会生成类似 time (tar -c stock_file | lz4 > stock_file.lz4) 的东西,但如果我写一个小程序:

#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;
}

然后我将它构建为 pretending_time 和 运行 它:

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

好吧好吧,参数是well不是well | cat,那我去查一下time的源码,搞清楚time是怎么取well | cat作为一个参数

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

只有一个文件源码,感觉不错

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

  ......
}

感觉不好,慎重编译

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

什么是

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

没见过,编译不了,c-lang允许吗?这是 time 在参数中使用管道符号 | 的方式吗?

疑惑解决后编辑

我的 shell 中有一个内置命令 time,但是 which 会找到独立的 time 实用程序,如果 [=30] 有内置命令,你可以=]

shell@kernel: ~> help | grep -Eo "\btime .*"
time [-p] pipeline

time 的行为与其他(外部)程序不同的原因是因为 time 实际上不是一个程序,它是一个 bash 内置程序。为了进行比较,请考虑以下示例:使用 bash 内置函数,我们得到

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

而使用外部时间

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

正如您所见,在第一种情况下,time 乘以两个 sleep 操作,而在第二种情况下,它仅乘以第一个 sleep。通常,不可能将 time 的版本构建为像第一个示例那样工作的外部程序。原因是每当 bash 看到管道字符时,它会独立执行左边的东西和右边的东西。所以左边永远没有机会看到右边命令的样子。另一方面,通过内置time,bash可以识别它并对其进行特殊处理。