time command1 | command2
Does time
apply to command1
or command1 | command2
?
time
is usually implemented in two ways: as an external command and as an internal feature of a given shell (I say "feature" because it depends on how the shell implements it, though I've only seen it as a reserved word). So, assuming there's at least an external time
on the system, the actual answer depends on which shell the user is running and, if applicable, how time
is implemented in such shell.
According to the tags you are using Bash as your shell, which has an internal time
, and I'll assume GNU time
as the external one for simplicity's sake.
Bash time
:
- Is a reserved word.
- It applies to entire pipelines.
- It can be used with internal commands/functions/reserved words.
GNU time
:
- Is an external command.
- It applies to simple commands.
- It cannot be used with internal commands/functions/reserved words unless these were invoked within a shell.
In your specific scenario, as you are running Bash, time
applies to command1 | command2
. If you were using a shell without an internal time
but an external time
is present on the system, it would apply to command1
.
Q: If your answer is one of the two, how would you specify the other?
Applying time
to command1
within Bash:
Using { … }
to limit time
's scope:
{ time command1; } | command2
Running the external time
command:
# 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
Applying time
to command1 | command2
with GNU time
:
Placing the pipeline in an external file and running it:
time ./script.sh
Invoking a shell and running the pipeline within it:
time sh -c 'command1 | command2'
Q: Could you explain your answer based on the grammar of bash or how the shell interprets the command?
Bash documents its time
in the 3.2.2 Pipelines chapter of its manual:
The format for a pipeline is
[time [-p]] [!] command1 [ | or |& command2 ] …
The reserved word time
causes timing statistics to be printed for the pipeline once it finishes.
GNU time
documentation is available via info time
and man time
:
The format of the time
command is:
time [option...] COMMAND [ARG...]
time
runs the program COMMAND
, with any given arguments ARG...
. When COMMAND
finishes, time
displays information about resources used by COMMAND
.
POSIX documents the standard time
, which is the base for many time
implementations:
SYNOPSIS
time [-p] utility [argument...]
DESCRIPTION
The time
utility shall invoke the utility named by the utility
operand with arguments supplied as the argument
operands and write a message to standard error that lists timing statistics for the utility.
When time
is used as part of a pipeline, the times reported are unspecified, except when it is the sole command within a grouping command (see Grouping Commands) in that pipeline.
RATIONALE
In the KornShell, time
is a shell reserved word that can be used to time an entire pipeline, rather than just a simple command. The POSIX definition has been worded to allow this implementation.
The term utility
is used, rather than command
, to highlight the fact that shell compound commands, pipelines, special built-ins, and so on, cannot be used directly. However, utility
includes user application programs and shell scripts, not just the standard utilities.
Q: When the shell parses the command, does it recognize time
as a reserved word before recognizing |
as a control operator?
While Bash's manual does not explicitly mention this information, POSIX clearly states the order of recognition:
2.10.1 Shell Grammar Lexical Conventions
The input language to the shell must be first recognized at the character level. The resulting tokens shall be classified by their immediate context according to the following rules (applied in order). These rules shall be used to determine what a "token" is that is subject to parsing at the token level. The rules for token recognition in Token Recognition shall apply.
- If the token is an operator, the token identifier for that operator shall result.
- If the string consists solely of digits and the delimiter character is one of
<
or >
, the token identifier IO_NUMBER shall be returned.
- Otherwise, the token identifier TOKEN results.
Further distinction on TOKEN is context-dependent. It may be that the same TOKEN yields WORD, a NAME, an ASSIGNMENT_WORD, or one of the reserved words below, dependent upon the context.
In short: operators are recognized before reserved words.
Q: Does the order between recognizing time
as a reserved word and recognizing |
as a control operator determines whether time
applies to command1
or command1 | command2
?
Not really, even if time
is keep as a reserved word it could be programmed to apply to simple commands instead of entire pipelines (though I don't know any shell which has done this). What matters is how time
is implemented, not its order of recognition.
time
applies to the pipeline or just its first component. – Tim May 18 '18 at 03:50time
applies tocommand1
orcommand1 | command2
?" The "order" of what? I'm writting an answer so I'd want to know what you meant by this. – nxnev May 18 '18 at 04:11