Mientras discutía sobre las diferencias entre /usr/bin/timey el shell (bash y zsh) incorporado time, alguien mencionó que se puede usar \timecomo una abreviatura para obtener /usr/bin/time.
Primero parecía un buen atajo inocente, pero luego surgieron algunas preguntas:
- ¿Por qué
t\imefunciona también? - ¿Por qué
\cdcambia el directorio, aunque/usr/bin/cd¹ no?
Entonces, obviamente, \foono es equivalente a $(which foo). La pregunta ahora es:
¿El comportamiento observado \footanto en bash como en 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/cdes, en mi sistema,
#!/bin/sh
builtin cd "$@"
shell
quoting
posix
time-utility
Jonas Schäfer
fuente
fuente

Respuestas:
t\imeo\cd(o"tim"eo'cd'o${-##*}timeo${-+time}y cualquier otra combinación de citas y expansiones en las que pueda pensar que eventualmente se resolveríatimeocd), es eso: otra forma de escribircdytime.Sin embargo, que con el tiempo a resolver
cdotimeen un momento posterior del analizador sintáctico de la cáscara y la interpretación. En particular, eso sucede mucho después de que se produce el reconocimiento de palabras clave de shell y la sustitución de alias .Entonces, en el momento en que el shell busca palabras clave en su idioma, no lo reconoce
ti\mecomo latimepalabra clave del shell. Entonces a:sería reconocido por el shell como un comando simple en lugar de la
timepalabra clave seguida de un comando simple.Luego
ti\me, se procesaría la cita (aquí la barra invertida está citando elmcarácter que no necesita cita de todos modos, el carácter de cita se elimina, se obtienetime) y se buscaría untimecomando como cualquier otro comando (en la lista de incorporados , funciones y archivos ejecutables$PATH. Lo más probable es que esté/bin/timeaquí)Para
cd, no haycdpalabra clave en el lenguaje de shell, solo uncdcomando incorporado (que tiene prioridad sobre su/usr/bin/cd). Sin embargo, si define un alias paracd(likealias cd=pushd), lo mismo de nuevo. Como la sustitución de alias se realiza muy temprano, antes de eliminar las comillas, si tiene un alias paracdy no uno para\cd(tenga en cuenta que no muchos shells permiten alias con barras invertidas en ellos), luego escribiendo:te estás asegurando de que tu
cdalias no esté sustituido.En resumen, citando un nombre de comando o cualquier parte de ella le impide ser visto como una palabra clave de shell (palabras clave ser cosas como
while,for,if,{...timees una palabra clave en algunos sólo conchas), y no pasa por un alias que pueda tener para él .Sin embargo, no obliga a ese comando a resolverse en un archivo ejecutable
$PATH, el comando todavía se busca primero entre las funciones (que puede solucionar haciendocommand time cmd...) y las incorporadas (que puede solucionar haciendoenv time cmd..., aunque no sé de un shell que tiene untimecomando incorporado ).Tenga en cuenta que las citas también pueden influir en el comportamiento de los componentes especiales de la familia
typeset/declare/export/local... en algunos depósitos. Consulte ¿Se necesitan cotizaciones para la asignación de variables locales? para detalles.fuente
timey locdque conduce a la diferencia en el comportamiento observado es quetimees una palabra clave ycdes un comando incorporado .timees una palabra clave ycdno lo es. (y si tuviera un alias paracdotime, eso sería otro asunto). Esocdestá incorporado o no tiene incidencia en este punto (en lo que respecta a la influencia de las citas). Sin embargo, algunos shells tienen algunas incorporaciones que están a medio camino entre las palabras clave y las incorporadas, ya que su análisis se realiza de manera diferente a otras incorporaciones. Ese es el caso deexport/typeset/declare. Probablemente debería agregar alguna nota al respecto en esta respuesta.