2009-02-26 18 views
143

A menudo encuentro Bash sintaxis muy útil, p. sustitución de proceso como en diff <(sort file1) <(sort file2).¿Cómo puedo usar la sintaxis Bash en los objetos Makefile?

¿Es posible utilizar tales comandos Bash en un Makefile? Estoy pensando en algo como esto:

file-differences: 
    diff <(sort file1) <(sort file2) > [email protected] 

En mi GNU Make 3.80 que esto dará un error, ya que utiliza el shell en lugar de bash para ejecutar los comandos.

Respuesta

258

De la documentación GNU Make,

5.3.1 Choosing the Shell 
------------------------ 

The program used as the shell is taken from the variable `SHELL'. If 
this variable is not set in your makefile, the program `/bin/sh' is 
used as the shell. 

Así que ponga SHELL := /bin/bash en la parte superior de su archivo MAKE, y usted debe ser bueno para ir.

BTW: También puede hacer esto para un objetivo, al menos para GNU Make. Cada objetivo puede tener sus propias asignaciones de variables, como esto:

all: a b 

a: 
    @echo "a is $$0" 

b: SHELL:=/bin/bash # HERE: this is setting the shell for b only 
b: 
    @echo "b is $$0" 

Eso va a imprimir:

a is /bin/sh 
b is /bin/bash 

consulte "Valores de variables específicas de la diana" en la documentación para más detalles. Esa línea puede ir a cualquier parte en el Makefile, no tiene que ser inmediatamente antes del objetivo.

+21

500 generosidad esperando una cita de 'hombre'. Hablar sobre los tiempos : P – SiddharthaRT

+3

@inLoveWithPython Bueno, 'info', en realidad, pero creo que realmente ayudó a Andy. Sé que he tenido días como ese ... – derobert

+2

en caso de duda, @derobert significa literalmente: 'SHELL =/bin/bash' como la primera línea del Makefile (o justo después del comentario). –

10

Puede llamar bash directamente, utilice el -c bandera:

bash -c "diff <(sort file1) <(sort file2) > [email protected]" 

Por supuesto, es posible que no sea capaz de redirigir a la variable $ @, pero cuando traté de hacer esto, tengo -bash: [email protected]: ambiguous redirect como un mensaje de error, por lo que es posible que desee examinar eso antes de que se meta en esto (aunque estoy usando bash 3.2.algo, entonces tal vez el suyo funciona de manera diferente).

2

Puede llamar golpe directamente en el Makefile en lugar de utilizar el shell por defecto:

bash -c "ls -al" 

en lugar de:

ls -al 
+0

Tenga en cuenta que 'make' ignora el valor de la variable de entorno SHELL. – choroba

4

Si la portabilidad es importante que usted puede no querer depender de una carcasa específica en tu Makefile No todos los entornos tienen Bash disponible.

1

Hay una forma de hacerlo sin configurar explícitamente la variable SHELL para que apunte a bash. Esto puede ser útil si tiene muchos archivos make ya que SHELL no es heredado por makefiles posteriores o tomado del entorno. También debe asegurarse de que cualquier persona que compile su código configure su sistema de esta manera.

Si ejecuta sudo dpkg-reconfigure dash y responde 'no' al aviso, su sistema no usará dash como shell predeterminado. Luego apuntará a bash (al menos en Ubuntu). Tenga en cuenta que el uso de dash como el shell de su sistema es un poco más eficiente.

+1

Cuando se invoca bajo el nombre 'sh', bash se ejecuta en modo compatibilidad (' set -o posix'). La funcionalidad que OP está tratando de usar, la sustitución de procesos, no está disponible en este modo. –

Cuestiones relacionadas