O que `\ time`,` t \ ime` e `\ cd` realmente fazem? (diversão com barras invertidas em conchas)

9

Enquanto discutia sobre as diferenças entre /usr/bin/timee o shell (bash e zsh) time, alguém mencionou que alguém pode usar isso \timecomo uma abreviação para obter /usr/bin/time.

Primeiro, parecia um atalho inocente, mas surgiram algumas perguntas:

  • Por que t\imetambém funciona?
  • Por que \cdalterar o diretório, mesmo que /usr/bin/cd¹ não?

Então, obviamente, \foonão é equivalente a $(which foo). A questão agora é:

O comportamento observado \foono 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/cdno meu sistema,

#!/bin/sh
builtin cd "$@"
Jonas Schäfer
fonte
Consulte também unix.stackexchange.com/questions/12762/… Observe que \ command é uma funcionalidade tcsh especificamente documentada que diz para ignorar aliases para o comando.
simpleuser 16/03/16

Respostas:

14

t\imeou \cd(ou ou "tim"eou 'cd'ou ${-##*}timeou ${-+time}qualquer outra combinação de citações e expansões que você possa pensar que acabaria resolvendo para timeou cd), é: outra maneira de escrever cde time.

No entanto, isso acabaria resolvendo para cdou timeposteriormente 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\mecomo a timepalavra-chave shell. Então um:

ti\me echo test

seria reconhecido pelo shell como um comando simples, em oposição à timepalavra - chave seguida por um comando simples.

Em seguida, a citação ti\meseria processada (aqui que a barra invertida está citando o mcaractere que não precisa ser citado de qualquer maneira, o caractere de citação é removido, você obtém time) e um time comando seria pesquisado como qualquer outro comando (na lista de recursos internos) , funções e arquivos executáveis $PATH. É provável que esteja /bin/timeaqui)

Pois cd, não há cdpalavra-chave na linguagem shell, apenas um cdcomando interno (que tem precedência sobre o seu /usr/bin/cd). No entanto, se você definir um alias para cd(like alias 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 para cde não um \cd(observe que poucas conchas permitem aliases com barras invertidas), então escreva:

\cd dir

você está certificando-se de que seu cdalias 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 fazendo command time cmd...) e builtins (que você pode contornar executando env time cmd..., embora eu não conheça um shell que possui um timecomando 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.

Stéphane Chazelas
fonte
Então, a diferença entre timee o cdque leva à diferença no comportamento observado é que timeé uma palavra - chave e cdum comando interno ?
Jonas Schäfer
1
@JonasWielicki, é que timeé uma palavra-chave e cdnão é. (e se você tivesse um alias para cdou time, isso seria outra questão). Isso cdestá 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 de export/ typeset/ declare. Eu provavelmente deveria adicionar alguma nota sobre isso nesta resposta.
Stéphane Chazelas 15/03/16