我们如何让“时间”适用于管道或其组件?

Tim*_*Tim 1 bash pipe time

time command1 | command2
Run Code Online (Sandbox Code Playgroud)

time适用command1command1 | command2?如果你的答案是两者之一,你会如何指定另一个?

您能否根据 bash 的语法或 shell 如何解释命令来解释您的答案?

shell解析命令的时候,time在识别|为控制操作符之前是否识别为保留字?识别time为保留字和识别|为控制运算符之间的顺序是否决定time适用于command1command1 | command2

谢谢。

nxn*_*nev 7

time command1 | command2
Run Code Online (Sandbox Code Playgroud)

time适用command1command1 | command2

time通常以两种方式实现:作为外部命令和给定 shell 的内部特性(我说“特性”是因为它取决于 shell 如何实现它,尽管我只将它视为一个保留字)。因此,假设time系统上至少有一个外部,实际答案取决于用户正在运行的 shell,以及如果适用,time在这样的 shell 中是如何实现的

根据您使用 Bash 作为 shell 的标签,它有一个内部的timetime为了简单起见,我假设 GNU作为外部的。

重击time

  • 是保留字。
  • 它适用于整个管道。
  • 它可以与内部命令/功能/保留字一起使用。

GNU time:

  • 是外部命令。
  • 它适用于简单的命令。
  • 它不能与内部命令/函数/保留字一起使用,除非它们是在 shell 中调用的。

在您的特定场景中,当您运行 Bash 时,time适用于command1 | command2. 如果您使用的外壳没有内部timetime系统上存在外部,则它将适用于command1.


问:如果你的答案是两者之一,你会如何指定另一个?

应用timecommand1内击:

  • 使用{ … }到极限time的范围:

    { time command1; } | command2
    
    Run Code Online (Sandbox Code Playgroud)
  • 运行外部time命令:

    # Using the `command` builtin
    command time command1 | command2
    
    # Using `env`
    env time command1 | command2
    
    # Escaping/quoting the `time` word
    \time command1 | command2
    'time' command1 | command2
    
    # Explicitly running the external `time` command
    /usr/bin/time command1 | command2
    
    Run Code Online (Sandbox Code Playgroud)

应用timecommand1 | command2与GNU time


问:能否根据bash的语法或者shell如何解释命令来解释你的答案?

Bashtime在其手册的3.2.2 Pipelines章节中记录了它:

管道的格式是

[time [-p]] [!] command1 [ | or |& command2 ] …
Run Code Online (Sandbox Code Playgroud)

time一旦管道完成,保留字会导致为管道打印计时统计信息。

GNUtime文档可通过info time和 获得man time

time命令的格式为:

time [option...] COMMAND [ARG...]
Run Code Online (Sandbox Code Playgroud)

timeCOMMAND使用任何给定的参数运行程序ARG...。当COMMAND完成后,time显示有关所用资源的信息COMMAND

POSIX 记录了标准time,这是许多time实现的基础:

概要

time [-p] utility [argument...]
Run Code Online (Sandbox Code Playgroud)

描述

time实用程序应调用由utility操作数命名的实用程序,并提供作为操作数的参数,并将argument消息写入标准错误,列出该实用程序的计时统计信息。

time用作管道的一部分时,报告的时间未指定,除非它是该管道中分组命令中的唯一命令(请参阅分组命令)。

基本原理

在 KornShell 中,time是一个 shell 保留字,可用于对整个管道进行计时,而不仅仅是一个简单的命令。POSIX 定义的措辞允许这种实现。

使用该术语utility而不是command来强调不能直接使用 shell 复合命令、管道、特殊内置程序等的事实。但是,utility包括用户应用程序和 shell 脚本,而不仅仅是标准实用程序。


Q: shell在解析命令时,是否time先识别|为保留字,再识别为控制符?

虽然 Bash 的手册没有明确提到这个信息,但POSIX 清楚地说明了识别顺序:

2.10.1 Shell 语法词汇约定

必须首先在字符级别识别外壳的输入语言。结果令牌应根据以下规则(按顺序应用)按其直接上下文进行分类。这些规则将用于确定在令牌级别进行解析的“令牌”是什么。适用Token Recognition中的Token识别规则。

  1. 如果令牌是一个运算符,则应生成该运算符的令牌标识符。
  2. 如果字符串仅由数字组成并且分隔符是<or 之一>,则应返回令牌标识符IO_NUMBER
  3. 否则,令牌标识符TOKEN结果。

TOKEN 的进一步区分取决于上下文。可能是同一个TOKEN产生WORDNAMEASSIGNMENT_WORD或下面的保留字之一,具体取决于上下文。

简而言之:在保留字之前识别运算符


问:识别time为保留字和识别|为控制运算符之间的顺序是否决定time适用于command1command1 | command2

并非如此,即使time保留为保留字,也可以对其进行编程以应用于简单命令而不是整个管道(尽管我不知道任何已完成此操作的外壳程序)。重要的是如何time实施,而不是识别顺序