Enquanto discutia sobre as diferenças entre /usr/bin/time
e o shell (bash e zsh) time
, alguém mencionou que alguém pode usar isso \time
como uma abreviação para obter /usr/bin/time
.
Primeiro, parecia um atalho inocente, mas surgiram algumas perguntas:
- Por que
t\ime
também funciona? - Por que
\cd
alterar o diretório, mesmo que/usr/bin/cd
¹ não?
Então, obviamente, \foo
não é equivalente a $(which foo)
. A questão agora é:
O comportamento observado \foo
no bash e no zsh é coberto pela definição POSIX de um shell e, se sim, por que ele se comporta como?
Nota de rodapé 1: /usr/bin/cd
no meu sistema,
#!/bin/sh
builtin cd "$@"
shell
quoting
posix
time-utility
Jonas Schäfer
fonte
fonte
Respostas:
t\ime
ou\cd
(ou ou"tim"e
ou'cd'
ou${-##*}time
ou${-+time}
qualquer outra combinação de citações e expansões que você possa pensar que acabaria resolvendo paratime
oucd
), é: outra maneira de escrevercd
etime
.No entanto, isso acabaria resolvendo para
cd
outime
posteriormente a análise e interpretação da sintaxe do shell. Em particular, isso acontece muito depois do reconhecimento de palavras-chave do shell e da substituição de alias .Portanto, no momento em que o shell procura palavras-chave em seu idioma, não é reconhecido
ti\me
como atime
palavra-chave shell. Então um:seria reconhecido pelo shell como um comando simples, em oposição à
time
palavra - chave seguida por um comando simples.Em seguida, a citação
ti\me
seria processada (aqui que a barra invertida está citando om
caractere que não precisa ser citado de qualquer maneira, o caractere de citação é removido, você obtémtime
) e umtime
comando seria pesquisado como qualquer outro comando (na lista de recursos internos) , funções e arquivos executáveis$PATH
. É provável que esteja/bin/time
aqui)Pois
cd
, não hácd
palavra-chave na linguagem shell, apenas umcd
comando interno (que tem precedência sobre o seu/usr/bin/cd
). No entanto, se você definir um alias paracd
(likealias cd=pushd
), o mesmo novamente. Como a substituição do alias é feita muito cedo, antes da remoção da cotação, se você tiver um alias paracd
e não um\cd
(observe que poucas conchas permitem aliases com barras invertidas), então escreva:você está certificando-se de que seu
cd
alias não seja substituído.Em suma, citando um nome de comando ou qualquer parte dele a impede de ser visto como uma palavra-chave shell (palavras-chave a ser coisas como
while
,for
,if
,{
...time
é uma palavra-chave em alguns apenas conchas), e ignora um alias você pode ter para ele .No entanto, ele não força esse comando a resolver para um arquivo executável
$PATH
, o comando ainda é pesquisado primeiro entre funções (que você pode contornar fazendocommand time cmd...
) e builtins (que você pode contornar executandoenv time cmd...
, embora eu não conheça um shell que possui umtime
comando interno ).Observe que a citação também pode influenciar o comportamento dos componentes especiais da família
typeset
/declare
/export
/local
... em alguns shells. Consulte São necessárias cotações para atribuição de variável local? para detalhes.fonte
time
e ocd
que leva à diferença no comportamento observado é quetime
é uma palavra - chave ecd
um comando interno ?time
é uma palavra-chave ecd
não é. (e se você tivesse um alias paracd
outime
, isso seria outra questão). Issocd
está embutido ou não, não tem incidência neste momento (no que diz respeito à influência da citação). No entanto, algumas shells têm alguns componentes internos que estão a meio caminho entre palavras-chave e componentes internos, pois sua análise é feita de maneira diferente de outros componentes internos. Esse é o caso deexport
/typeset
/declare
. Eu provavelmente deveria adicionar alguma nota sobre isso nesta resposta.