¿Qué hace `\ time`,` t \ ime` y `\ cd` en realidad? (diversión con barras diagonales en proyectiles)

Al debatir sobre las diferencias entre /usr/bin/time y el shell incorporado (bash y zsh), alguien mencionó que se puede usar \time como una abreviatura para get /usr/bin/time .

Primero parecía un buen atajo inocente, pero luego surgieron algunas preguntas:

  • ¿Por qué también funciona?
  • ¿Por qué \cd cambia el directory, a pesar de que /usr/bin/cd ¹ no?

Entonces, obviamente, \foo no es equivalente a $(which foo) . La pregunta es ahora:

¿El comportamiento observado de \foo en bash y zsh está cubierto de alguna manera por la definición POSIX de un shell, y si es así, por qué se comporta como lo hace?


Nota 1: /usr/bin/cd es, en mi sistema,

 #!/bin/sh builtin cd "$@" 

Solutions Collecting From Web of "¿Qué hace `\ time`,` t \ ime` y `\ cd` en realidad? (diversión con barras diagonales en proyectiles)"

t\ime o \cd (o "tim"e o 'cd' o ${-##*}time o ${-+time} y cualquier otra combinación de presupuestos y expansiones que se pueda pensar que eventualmente resolvería el time o cd ), es eso: otra forma de escribir cd y time .

Sin embargo, eso eventualmente resolvería el cd o el time en un momento posterior del análisis sintáctico y la interpretación de la syntax. En particular, eso ocurre mucho después de que tenga lugar el reconocimiento de palabra key de shell y la sustitución de alias .

Por lo tanto, en el momento en que el intérprete de commands busca palabras key en su idioma, no reconoce ti\me como la palabra key time shell. Entonces a:

 ti\me echo test 

Sería reconocido por el intérprete de commands como un command simple en lugar de la palabra key del time seguida por un command simple.

Luego se procesarán las citas en ti\me (aquí la barra diagonal está citando el carácter m que no necesita citar de todos modos, se quita el carácter de comillas, se obtiene time ) y un command de time searchía como cualquier otro command (en la list de commands, funciones y files ejecutables en $PATH . Lo más probable es que sea /bin/time aquí)

Para cd , no hay palabra key cd en el idioma del shell, solo un command incorporado cd (que tiene prioridad sobre su /usr/bin/cd ). Sin embargo, si define un alias para cd (como alias cd=pushd ), lo mismo nuevamente. Como la sustitución de alias se realiza muy temprano, antes de eliminar comillas, si tiene un alias para cd y no uno para \cd (tenga en count que no hay muchos shells que permitan alias con barras invertidas en ellos), entonces escribiendo:

 \cd dir 

estás asegurándote de que tu alias de cd no esté sustituido.

En resumen, al citar un nombre de command o cualquier parte del mismo se evita que se vea como una palabra key shell (las palabras key son while , for , if , {time es una palabra key solo en algunos shells) y omite un alias puedes tenerlo.

Sin embargo, no obliga a ese command a resolver en un file ejecutable en $PATH , el command aún se busca primero entre las funciones (que puede utilizar haciendo el command time cmd... ) y builtins (que puede trabajar haciendo env time cmd... , aunque no conozco un shell que tenga un command de time incorporado).

Tenga en count que las comillas también pueden influir en el comportamiento de los builtins especiales de la familia typeset / declare / export / local … en algunos shells. Ver ¿Se necesitan presupuestos para la asignación de variables locales? para detalles.