El escenario clásico con precedencia de operador, tiene una línea como:
(cd ~/screenshots/ && ls screenshot* | head -n 5)
Y no sabes si está analizado ((A && B) | C)
o (A && B | C)
...
La documentación casi oficial que se encuentra aquí no enumera la tubería en la lista, por lo que no puedo simplemente verificar en la tabla.
Además, en bash, (
no es solo para cambiar el orden de las operaciones, sino que crea una subshell , por lo que no estoy 100% seguro de que estas líneas sean el equivalente de la línea anterior:
((cd ~/screenshots/ && ls screenshot*) | head -n 5)
En términos más generales, ¿cómo saber el AST de una línea bash? En python tengo una función que me da el árbol para que pueda verificar fácilmente el orden de operación.
bash
está usando un analizador yacc no algo ad-hoc; si lo ejecuta yacc -v
, obtendrá y.output
una gramática agradable que lo muestra &&
y ||
combina listas, y las listas finalmente se componen de tuberías (y no al revés); tl; dr; A && B | C
es lo mismo que A && { B | C; }
, como se esperaba. No asuma ningún orden de ejecución entre B
y C
; Los comandos en una tubería se ejecutan en paralelo .
[...]
pruebas y $((...))
evaluaciones aritméticas; en particular, ||
y &&
como se usa con la lista de comandos en el lenguaje de shell tiene la misma precedencia , a diferencia de los operadores respectivos en C
o en la evaluación aritmética (donde se &&
une más estrechamente que ||
).
|
es solo un conector que se ajusta a la salida estándar LHS a la entrada estándar RHS. Entonces, si elcd
comando en su ejemplo falla, no enviaría ninguna salidahead
, perohead
de hecho aúnexecute
analizaría la nada y no devolvería ninguna salida.