Mientras discutía sobre las diferencias entre /usr/bin/time
y el shell (bash y zsh) incorporado time
, alguien mencionó que se puede usar \time
como una abreviatura para obtener /usr/bin/time
.
Primero parecía un buen atajo inocente, pero luego surgieron algunas preguntas:
- ¿Por qué
t\ime
funciona también? - ¿Por qué
\cd
cambia el directorio, aunque/usr/bin/cd
¹ no?
Entonces, obviamente, \foo
no es equivalente a $(which foo)
. La pregunta ahora es:
¿El comportamiento observado \foo
tanto 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/cd
es, en mi sistema,
#!/bin/sh
builtin cd "$@"
shell
quoting
posix
time-utility
Jonas Schäfer
fuente
fuente
Respuestas:
t\ime
o\cd
(o"tim"e
o'cd'
o${-##*}time
o${-+time}
y cualquier otra combinación de citas y expansiones en las que pueda pensar que eventualmente se resolveríatime
ocd
), es eso: otra forma de escribircd
ytime
.Sin embargo, que con el tiempo a resolver
cd
otime
en 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\me
como latime
palabra clave del shell. Entonces a:sería reconocido por el shell como un comando simple en lugar de la
time
palabra clave seguida de un comando simple.Luego
ti\me
, se procesaría la cita (aquí la barra invertida está citando elm
carácter que no necesita cita de todos modos, el carácter de cita se elimina, se obtienetime
) y se buscaría untime
comando como cualquier otro comando (en la lista de incorporados , funciones y archivos ejecutables$PATH
. Lo más probable es que esté/bin/time
aquí)Para
cd
, no haycd
palabra clave en el lenguaje de shell, solo uncd
comando 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 paracd
y 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
cd
alias 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
,{
...time
es 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 untime
comando 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
time
y locd
que conduce a la diferencia en el comportamiento observado es quetime
es una palabra clave ycd
es un comando incorporado .time
es una palabra clave ycd
no lo es. (y si tuviera un alias paracd
otime
, eso sería otro asunto). Esocd
está 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.