¿Por qué no hay un ;
carácter después do
de los bucles de shell cuando se escribe en una sola línea?
Esto es lo que quiero decir. Cuando se escribe en varias líneas, un for
bucle se ve así:
$ for i in $(jot 2)
> do
> echo $i
> done
Y en una sola línea:
$ for i in $(jot 2); do echo $i; done
Todas las líneas contraídas aparecen ;
después de ellas, excepto la do
línea, y si incluye el ;
, es un error. Alguien probablemente mucho más inteligente que yo decidió que esto era lo correcto por una razón, pero no puedo entender cuál es la razón. Me parece inconsistente.
Lo mismo con los while
bucles también.
$ while something
> do
> anotherthing
> done
$ while something; do anotherthing; done
while
y coma después /for
tampoco.Respuestas:
Esa es la sintaxis del comando. Ver comandos compuestos
Nota específicamente:
do commands
La mayoría de las personas ponen el
do
ycommands
en una línea separada para permitir una lectura más fácil, pero no es necesario, podría escribir:Sé que esta pregunta es específicamente sobre shell y la he vinculado al manual de bash. No está escrito de esa manera en el manual de shell, pero está escrito de esa manera en un artículo escrito por Stephen Bourne para la revista byte.
Stephen dice:
fuente
for i in thing; do; something; done
. Aunque se permite un salto de línea, no se permite un punto y coma.something
es el tema y sedo
aplica a él. Al igual que en la estructura de la oración en inglés.while
sintaxis), por lo que necesita algo para diferenciar los comandos de condición de los comandos del cuerpo del bucle. Usardo
para separarlos es probablemente lo que parecía más apropiado.No sé cuál es la razón original de esta sintaxis, pero consideremos el hecho de que los
while
bucles pueden tomar múltiples comandos en la sección de condición, por ejemploAquí, la
do
palabra clave es necesaria para distinguir la sección de condición y el cuerpo principal del bucle.do
es una palabra clave comowhile
,if
ythen
(ydone
), y parece estar en línea con las otras que no requiere un punto y coma o una nueva línea después, sino que aparece inmediatamente antes de un comando.La alternativa (generalizada
if
ywhile
) se vería algo fea, tendríamos que escribir, por ejemploLa sintaxis de los
for
bucles es similar.fuente
La sintaxis de Shell está basada en prefijo. Tiene cláusulas introducidas por palabras clave especiales. Ciertas cláusulas tienen que ir juntas.
Un
while
bucle se compone de uno o más comandos de prueba:y por uno o más comandos del cuerpo:
Algo tiene que decirle al shell que comienza un ciclo while. Ese es el propósito de la
while
palabra:Pero entonces, las cosas son ambiguas. ¿Qué comando es el comienzo del cuerpo? Algo tiene que indicar eso, y eso es lo
do
que hace el prefijo:y, finalmente, algo tiene que indicar que se ha visto el último cuerpo; una palabra clave especial
done
hace eso.Estas palabras clave de shell no requieren separación de punto y coma, incluso en la misma línea. Por ejemplo, si cierra varios bucles anidados, simplemente puede tener
done done done ...
.Más bien, el punto y coma se encuentra entre
... test ; body ...
si están en la misma línea. Se entiende que ese punto y coma es un terminador: pertenece altest
. Por lo tanto, sido
se inserta una palabra clave entre ellas, debe ir entre el punto y coma ybody
. Si estuviera al otro lado del punto y coma, estaría incorrectamente incrustado dentro de latest
sintaxis del comando, en lugar de colocarse entre los comandos.La sintaxis de shell fue diseñada originalmente por Stephen Bourne y está inspirada en Algol . Bourne amaba tanto a Algol que utilizó muchas macros de C en el código fuente del shell para hacer que C se pareciera a Algol. Puede explorar las fuentes de shell con fecha de 1979 de la Versión 7 de Unix . Las macros están adentro
mac.h
y se usan por todas partes. Por ejemplo,if
las declaraciones se representan comoIF
...ELSE
...ELIF
...FI
.fuente
Yo diría que eso
do
no es particularmente especial aquí. Obtiene un error porque;
no puede iniciar una lista de comandos. Si lo hiciera, el primer comando estaría vacío, y la gramática no permite comandos vacíos (asignaciones variables o redirecciones sin un comando, sí, pero absolutamente nada, no). Esto es cierto en cualquier número de lugares, donde se espera una lista de comandos:Incluso:
En todos estos lugares, se espera una lista de comandos, por lo que un inicio
;
es inesperado.fuente
do
(yif
etc.)?La sintaxis es:
Cualquiera de las nuevas líneas, ya sea en la lista de comandos o antes de "hacer" o "hecho", puede reemplazarse por un ";".
Se permite una nueva línea (pero no un ";") después del "hacer" y antes de la "entrada", solo para que las cosas se vean mejor, pero no tendría sentido exigir una nueva línea allí.
fuente
if
es similar con sus palabras clave: esto es bastante legible cuando los comandos son cortos:fuente
\n
después dedo
todo, tenía sentido (siempre y cuando no pienses en no poder poner un arbitrario\n
entre otros comandos y argumentos).do
,then
,else
¿no args - si lo fueran, que no estaría permitido el uso de un punto y coma delante de ellos. Son palabras clave de shell (vertype if then elif else fi
)Respuesta corta, porque esto está especificado por la gramática de shell POSIX . Cualquier cosa entre
do
ydone
se considera un grupo de declaraciones, mientras que;
es un separador secuencial:Además, si
;
fuera necesario, el estándar lo indicaría explícitamente e incluiríasequential_sep
despuésDo
.fuente
Porque hacer es una palabra clave y lo que sigue son esencialmente parámetros. El intérprete de Bash sabe que más sigue. Es similar a cómo no hay ';' siguiendo la i en el comando for. En realidad, puede agregar una nueva línea después de i para for y escribir el resto en una nueva línea y funcionará bien.
fuente