Sé de la precedencia de enlace relativa de los operadores ';', '&', '&&' o '||'
http://www.gnu.org/software/bash/manual/bashref.html#Lists
pero cuando las tuberías entran en escena junto con '&&', lucho por comprender la fuerza de unión y tropezar con un comando correcto o simplemente renunciar.
¿Cuál es la precedencia vinculante de '|' y '>' en comparación con lo anterior?
Ejemplo donde me confundo:
ls _thumbnails/video.mp4.jpg 2>/dev/null
&& echo "thumbnail already generated. Not regenerating" \
&& exit \
|| ffmpeg_thumbnail_create video.mp4 2>/dev/null \
&& ls _thumbnails/video.mp4.jpg \
&& echo "Thumbnail successfully created" \
&& exit \
|| echo "Thumbnail creation failed" \
| tee ~/thumbnails.log
El objetivo de lo anterior es crear una miniatura si y solo si no está presente (ejecuto un cronjob diario). Y no me gusta la gran cantidad de salida de ffmpeg cuando no hay error (que no es la forma de Unix). También hay otras situaciones, así que no empieces a darme consejos que usen declaraciones separadas u opciones especiales específicas para estos programas. Quiero entender la precedencia vinculante.
fuente
{
...}
debería funcionar. Podría haberlo intentado de forma no sistemática y no haber obtenido los resultados esperados.Respuestas:
La respuesta corta es que
<
,>
y sus variantes tienen la mayor precedencia de enlace (enlace más ajustado), seguidas de|
, seguidas de&&
y||
, seguidas de;
y&
. Por lo tanto, soloecho "Thumbnail creation failed"
se canaliza altee
.Una respuesta un poco más larga indicaría que la prioridad más alta es en realidad la agrupación, que se puede indicar con paréntesis o llaves. Por ejemplo,
y
son aproximadamente equivalentes a
Notas:
B
yC
ejecuta en un proceso hijo. Por lo tanto, los comandos como asignaciones variables ocd
no tendrán efecto en el shell principal. Los comandos entre llaves se ejecutan en el mismo proceso que elA
comando. Por lo tanto, el constructo de abrazaderaA && { B; C;}
está más cerca delif
-then
-else
constructo.{
y a;
(o a&
, o nueva línea) antes de}
.Para leer más, vea ¿Cuáles son los operadores de control y redireccionamiento del shell?y ¿ Cuándo es 'si' no es necesario? (particularmente mis respuestas).
Para obtener más información, consulte la página de manual bash (1) y la especificación / definición POSIX del lenguaje de comandos de Shell , específicamente la Sección 2.9, Comandos de Shell y la Sección 2.10.2, Reglas de gramática de Shell . Este es un intento de proporcionar algo de contexto para lo anterior:
Cosas como
myVar=42
IFS= read a
date
cd /some/directory
ls -laR dir1 dir2
cat foo* > /tmp/allfoo
ls -laR dir{1,2}
find . -type f -name "foo*" -print > /tmp/output 2> /dev/null
> newfile
[ -f catfood ]
exit
todos se consideran "comandos simples".
x=1 | od -ab
ols -laR | z=0
son sintácticamente válidas.son llamados "listas" por bash y "listas AND-OR" por POSIX. Una vez más, una "tubería" individual o incluso un "comando simple" individual se considera una "lista AND-OR", aunque no contenga un AND o un OR.
La nomenclatura comienza a ser un poco inconsistente. Bash llama a estas "listas" también; POSIX los llama "listas", "listas compuestas" y (raramente) "términos". Una vez más, una "lista AND-OR" individual, una "tubería" o incluso un "comando simple" individual se considera una "lista", aunque no contenga a
&
o a;
.y
y los comandos de control de flujo (
for
,if
-then
-else
,while
, etc.) se denominan “comandos compuestos”.En los ejemplos anteriores, es probable que tenga más sentido para interpretar
A
,B
yC
que sea tuberías. Recuerde, una "tubería" puede ser un "comando simple" individual; No necesita contener una tubería.fuente
(
..)
y{
..}
. De la mala experiencia anterior había concluido que los corchetes solo se usaban en el contexto de los "comandos dinámicos" (es decir,$(
..)
) ya que apenas podía lograr que hicieran algo en lo que respecta a la asociatividad.