Problema

Recientemente necesité ejecutar el comando diff sobre la salida de otros dos comandos. Es decir, diff recibe como parámetros los ficheros sobre los que se quiere mostrar las diferencias, pero yo buscaba hacer un diff a la salida de dos comandos, no dos ficheros. Un ejemplo:




$ diff $(readelf --all ./helloc) $(readelf --all ./hellocpp)

Este fue el comando que me vino a la cabeza inmediatamente, pero no funciona, ya que $() sustituye el resultado del comando en su interior, en este caso readelf. De este modo diff recibe como parámetros el resultado de ejecutar ese comando. Veamoslo más claro:


$ diff $(ls dir1) $(ls dir2)

Al sustituir el resultado de ls dir1, diff recibe como parámetros los ficheros del directorio 1, y no es eso lo que queremos. Queremos la diferencia entre ambos directorios.

Bastó una rápida consulta a Google para solucionar el problema.

Solución

En askubuntu, el usuario Ternary preguntó exáctamente lo mismo que yo intentaba resolver, Guilles proporcionó la solución, veamos:


$ diff <(readelf --all ./helloc) <(readelf --all ./hellocpp)

Listo, no es necesario nada más que reemplazar $ por <, esto realiza una sustitución de procesos en lugar de sustitución de comandos. El resultado es que ahora diff tendrá como parámetros descriptores de ficheros (diff /dev/fd/5 /dev/fd/6) correspondientes a dos pipes creadas por bash. Cuando diff abre dichos ficheros, se conecta al lado de lectura de cada pipe o tubería, mientras que el lado de escritura de cada tubería está conectado al comando readelf.

Referencias

Cómo ejecutar diff a la salida de dos comandosaskubuntu.com