Cuando ejecuto estos dos comandos, obtengo
$ type cd
cd is a shell builtin
$ type if
if is a shell keyword
Se muestra claramente que cd
es un shell incorporado y if
es una palabra clave de shell. Entonces, ¿cuál es la diferencia entre shell incorporado y palabra clave?
command-line
Avinash Raj
fuente
fuente
Respuestas:
Hay una gran diferencia entre una palabra clave y una incorporada, en la forma en que Bash analiza su código. Antes de hablar sobre la diferencia, enumeremos todas las palabras clave y las siguientes:
Construidos:
Palabras clave:
Tenga en cuenta que, por ejemplo,
[
es un incorporado y que[[
es una palabra clave. Usaré estos dos para ilustrar la diferencia a continuación, ya que son operadores bien conocidos: todos los conocen y los usan regularmente (o deberían).Bash escanea y comprende una palabra clave muy temprano en su análisis. Esto permite, por ejemplo, lo siguiente:
Esto funciona bien y Bash saldrá feliz
Tenga en cuenta que no cité
$string_with_spaces
. Mientras que lo siguiente:muestra que Bash no está contento:
¿Por qué funciona con palabras clave y no con builtins? porque cuando Bash analiza el código, ve
[[
cuál es una palabra clave y comprende muy pronto que es especial. Por lo tanto, buscará el cierre]]
y tratará el interior de una manera especial. Un builtin (o comando) se trata como un comando real que se llamará con argumentos. En este último ejemplo, bash entiende que debe ejecutar el comando[
con argumentos (se muestra uno por línea):ya que se produce la expansión variable, la eliminación de comillas, la expansión del nombre de ruta y la división de palabras. El comando
[
resulta estar construido en el shell, por lo que lo ejecuta con estos argumentos, lo que resulta en un error, de ahí la queja.En la práctica, verá que esta distinción permite un comportamiento sofisticado, que no sería posible con los builtins (o comandos).
Todavía en la práctica, ¿cómo puedes distinguir una palabra clave de una palabra clave? Este es un experimento divertido de realizar:
Cuando Bash analiza la línea
$a -d . ]
, no ve nada especial (es decir, sin alias, sin redireccionamientos, sin palabras clave), por lo que solo realiza una expansión variable. Después de expansiones variables, ve:por lo que se ejecuta el comando (incorporado)
[
con argumentos-d
,.
y]
, que, por supuesto, es verdad (esto sólo comprueba si.
es un directorio).Ahora mira:
Oh. Esto se debe a que cuando Bash ve esta línea, no ve nada especial y, por lo tanto, expande todas las variables y finalmente ve:
En este momento, las expansiones de alias y el escaneo de palabras clave se han realizado durante mucho tiempo y ya no se realizarán, por lo que Bash intenta encontrar el comando llamado
[[
, no lo encuentra y se queja.En la misma linea:
y
La expansión de alias es algo bastante especial también. Todos ustedes han hecho lo siguiente al menos una vez:
El razonamiento es el mismo: la expansión de alias ocurre mucho antes de la expansión variable y la eliminación de comillas.
Keyword vs Alias
¿Qué crees que sucede si definimos un alias como palabra clave?
¡Oh, funciona! ¡para que los alias se puedan usar para alias de palabras clave! bueno saber.
Conclusión: los builtins realmente se comportan como comandos: corresponden a una acción que se ejecuta con argumentos que se someten a expansión directa de variables y división de palabras y globbing. Realmente es como tener un comando externo en algún lugar
/bin
o/usr/bin
que se llama con los argumentos dados después de la expansión de variables, etc. Tenga en cuenta que cuando digo es realmente como tener un comando externo , solo me refiero a los argumentos, división de palabras, globbing, expansión variable, etc. ¡Un incorporado puede modificar el estado interno del shell!Las palabras clave, por otro lado, se escanean y se entienden muy temprano, y permiten un comportamiento sofisticado del shell: el shell podrá prohibir la división de palabras o la expansión del nombre de ruta, etc.
Ahora mire la lista de palabras clave y palabras clave e intente averiguar por qué algunas deben ser palabras clave.
!
es una palabra clave Parece que sería posible imitar su comportamiento con una función:pero esto prohibiría construcciones como:
o
Lo mismo para
time
: es más poderoso tener una palabra clave para que pueda cronometrar comandos compuestos complejos y tuberías con redireccionamientos:Si fuera
time
un mero comando (incluso incorporado), solo vería los argumentosgrep
,^#
y/home/gniourf/.bashrc
, cronometraría esto, y luego su salida pasaría por las partes restantes de la tubería. Pero con una palabra clave, ¡Bash puede manejar todo! ¡puedetime
la tubería completa, incluidas las redirecciones! Sitime
fuera un mero comando, no podríamos hacer:Intentalo:
Intenta arreglarlo:
Sin esperanza.
Palabra clave vs alias?
¿Qué crees que pasa?
Realmente, un builtin es como un comando, excepto que está construido en el shell, ¡mientras que una palabra clave es algo que permite un comportamiento sofisticado! podemos decir que es parte de la gramática del shell.
fuente
=\
'mediante el usoman
,apropos
yhelp
, y no he tenido suerte. ¿Alguna idea de dónde iría para encontrar esta información? Principalmente para que en el futuro pueda ver qué más hay allí, porque creo que me falta una fuente de referencia.\ll
,"ll"
o'll'
.[[
rendimiento\[[
, no se analiza como un alias. Derecho hasta ahora? Donde me perdí no me di cuenta de que la barra invertida era una cosa de citas en Bash, e intenté buscarlo bajo alias y palabras clave y me perdí por completo ... Todo bien ahora. En la sección Cita:> Una barra invertida no citada () es el carácter de escape.\[[
es un token único del tipo LiteralQuoteToken, en oposición al[[
cual será OpenTestKeywordToken, y eso requiere un]]
CloseTestKeywordToken de cierre para la compilación oroper / sintaxis correcta. Más tarde, en (4) LiteralQuoteToken se evaluará[[
como el nombre del comando / comando a ejecutar, y en (6) Bash vomitará porque no hay ningún[[
comando o comando incorporado. Agradable. Puedo olvidar los detalles precisos con el tiempo, pero en este momento la forma en que Bash ejecuta las cosas es mucho más clara para mí; gracias.man bash
los llamaSHELL BUILTIN COMMANDS
. Entonces, un "shell incorporado" es como un comando normal, comogrep
, etc., pero en lugar de estar contenido en un archivo separado, está integrado en el propio bash . Esto los hace funcionar más eficientemente que los comandos externos.Una palabra clave también está "codificada en Bash, pero a diferencia de una función incorporada, una palabra clave no es en sí misma un comando, sino una subunidad de una construcción de comando". Interpreto que esto significa que las palabras clave no tienen una función sola, sino que requieren comandos para hacer cualquier cosa. (Desde el enlace, otros ejemplos son
for
,while
,do
, y!
, y hay más en mi respuesta a su otra pregunta.)fuente
[[ is a shell keyword
pero[ is a shell builtin
. No tengo ni idea de porqué.[
existía como un comando separado en el día.[[
no está especificado por el estándar, por lo que los desarrolladores pueden elegir incluir eso como palabra clave o como incorporado.El manual de la línea de comandos que viene con Ubuntu no proporciona una definición de palabras clave, sin embargo, el manual en línea (ver nota al margen) y las especificaciones estándar del lenguaje de comando POSIX Shell , se refieren a estas como "palabras reservadas", y ambas proporcionan listas de ellas. Del estándar POSIX:
La clave aquí es que las palabras clave / palabras reservadas tienen un significado especial porque facilitan la sintaxis de la shell, sirven para señalar ciertos bloques de código como bucles, comandos compuestos, ramificaciones (si / caso), etc. Permiten formar declaraciones de comandos, pero por sí mismos - no hacer nada, y de hecho, si se introduce palabras clave como
for
,until
,case
- la cáscara se espera una declaración completa, de lo contrario - error de sintaxis:En el nivel del código fuente, las palabras reservadas para bash se definen en parese.y , mientras que los incorporados tienen un directorio completo dedicado a ellos.
Nota al margen
El índice GNU se muestra
[
como palabra reservada, sin embargo, es un comando incorporado de hecho.[[
por el contrario es una palabra reservada.Ver también: ¿ Diferencias entre palabra clave, palabra reservada y construcción?
fuente