Em bash
, time
é uma palavra reservada , então o shell pode analisá-lo do jeito que quiser e aplicar regras para ele.
Aqui está o código que mostra como a linha bash
parse começa com time
palavra reservada :
static int
time_command_acceptable ()
{
#if defined (COMMAND_TIMING)
int i;
if (posixly_correct && shell_compatibility_level > 41)
{
/* Quick check of the rest of the line to find the next token. If it
begins with a '-', Posix says to not return 'time' as the token.
This was interp 267. */
i = shell_input_line_index;
while (i < shell_input_line_len && (shell_input_line[i] == ' ' || shell_input_line[i] == '\t'))
i++;
if (shell_input_line[i] == '-')
return 0;
}
switch (last_read_token)
{
case 0:
case ';':
case '\n':
case AND_AND:
case OR_OR:
case '&':
case WHILE:
case DO:
case UNTIL:
case IF:
case THEN:
case ELIF:
case ELSE:
case '{': /* } */
case '(': /* )( */
case ')': /* only valid in case statement */
case BANG: /* ! time pipeline */
case TIME: /* time time pipeline */
case TIMEOPT: /* time -p time pipeline */
case TIMEIGN: /* time -p -- ... */
return 1;
default:
return 0;
}
#else
return 0;
#endif /* COMMAND_TIMING */
}
Você vê, time
pode ser seguido pela maioria dos outros bash
palavras reservadas.
No caso de comando externo, a regra normal foi aplicada, {
foi considerado entrada de /usr/bin/time
. }
sozinho é um token inválido e bash
aumenta o erro.
Em:
/usr/bin/time echo hello
external time
não chamou o shell embutido echo
, mas o comando echo
externo.
Um strace
verifica que:
$ strace -fe execve /usr/bin/time echo 1
execve("/usr/bin/time", ["/usr/bin/time", "echo", "1"], [/* 64 vars */]) = 0
Process 25161 attached
....
[pid 25161] execve("/usr/bin/echo", ["echo", "1"], [/* 64 vars */]) = -1 ENOENT (No such file or directory)
[pid 25161] execve("/bin/echo", ["echo", "1"], [/* 64 vars */]) = 0
1
[pid 25161] +++ exited with 0 +++
....
Aqui, time
externo procura sua variável PATH
para encontrar o comando executável. Isso também explica no caso de usar uma função, você tem Nenhum arquivo ou diretório porque não existe um comando chamado mytest
em seu PATH
.