
En un símbolo del sistema bash, se pueden ejecutar diferencias utilizando pseudoarchivos:
diff <(echo test) <(echo test)
Agregar esto tal como está en un Makefile falla:
all:
diff <(echo test) <(echo test)
El error (pista: /bin/sh apunta a /bin/bash en este sistema):
/bin/sh: -c: line 0: syntax error near unexpected token `('
/bin/sh: -c: line 0: `diff <(echo test) <(echo test)'
¿Qué significa? ¿Existe alguna manera de diferenciar dos salidas sin utilizar archivos temporales?
Respuesta1
/bin/sh
puede estar bash
en su sistema, pero cuando se invoque como sh
, bash
se ejecutará en modo POSIX (como si POSIXLY_CORRECT
estuviera definido o se iniciara con --posix
).
En este modo, las sustituciones de procesos no existen.
Soluciones:
Utilice archivos temporales explícitos:
all: command1 >tmpfile command2 | diff tmpfile - rm -f tmpfile
Utilice un
bash -c
script en línea:all: bash -c 'diff <(command1) <(command2)'
Defina la variable Makefile
SHELL
como/bin/bash
(o cualquiera que sea la rutabash
en su sistema):SHELL=/bin/bash
Si desea portabilidad, opte por la primera solución. Si está de acuerdo con una dependencia de bash
, elija la segunda. Si además no necesita preocuparse por make
implementaciones que no sean GNU, utilice la tercera.
Con respecto a la configuración SHELL
: el estándar POSIX dice que los ejecutables en Makefiles deben invocarse con la system()
función de la biblioteca C mediante make
. No se garantiza que esta función utilice la SHELL
variable de entorno (de hecho, el estándar desaconseja hacerlo). El estándar también va más allá al decir que configurar la variable Makefile SHELL
no debería afectar elVariable ambiental SHELL
. Sin embargo, en la mayoría de las implementaciones make
que conozco, la variable Makefile SHELL
se utilizará para ejecutar los comandos.
La sugerencia enla justificación de la make
utilidades utilizar bash -c
:
Se omitieron la característica histórica
MAKESHELL
y las características relacionadas proporcionadas por otras implementaciones.make
En algunas implementaciones, se utiliza para permitir que un usuario anule el shell que se utilizará para ejecutarmake
comandos. Esto era confuso; para un portátilmake
, el shell debe ser elegido por el escritor del archivo MAKE. Además, un escritor de archivos MAKE no puede exigir el uso de un shell alternativo y aun así considerar el archivo MAKE portátil. Si bien sería posible estandarizar un mecanismo para especificar un shell alternativo, las implementaciones existentes no están de acuerdo con dicho mecanismo, y los escritores de archivos MAKE ya pueden invocar un shell alternativo especificando el nombre del shell en la regla para un destino; Por ejemplo:
python -c "foo"