2009-02-26 9 views
143

Je trouve souvent Bash syntaxe très utile, par ex. substitution de processus comme dans diff <(sort file1) <(sort file2).Comment puis-je utiliser la syntaxe Bash dans les cibles Makefile?

Est-il possible d'utiliser de telles commandes Bash dans un Makefile? Je pense à quelque chose comme ceci:

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

Dans mon GNU Make 3,80 Cela vous donnera une erreur, car il utilise la shell au lieu de bash pour exécuter les commandes.

Répondre

258

De la GNU Make documentation,

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. 

donc mis SHELL := /bin/bash en haut de votre makefile, et vous devriez être bon d'aller.

BTW: Vous pouvez également le faire pour une cible, au moins pour GNU Make. Chaque cible peut avoir ses propres missions variables, comme ceci:

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" 

Ce imprimerons:

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

Voir « Valeurs variables spécifiques à la cible » dans la documentation pour plus de détails. Cette ligne peut aller n'importe où dans le Makefile, elle ne doit pas être immédiatement avant la cible.

+21

500 primes en attente d'une citation de 'man'. Parlez des horaires. : P – SiddharthaRT

+3

@inLoveWithPython Eh bien, 'info', en fait, mais, je suppose que ça a vraiment aidé Andy. Je sais que j'ai eu des jours comme ça ... – derobert

+2

en cas de doute, @derobert signifiait littéralement: 'SHELL =/bin/bash' comme première ligne du Makefile (ou juste après le commentaire). –

10

Vous pouvez appeler bash directement, utilisez le drapeau -c:

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

Bien sûr, vous ne pouvez pas être en mesure de rediriger vers la variable $ @ pour, mais quand j'ai essayé de le faire, je me suis -bash: [email protected]: ambiguous redirect comme un message d'erreur, donc vous voudrez peut-être y jeter un coup d'oeil avant d'entrer dans ce sujet (bien que j'utilise bash 3.2.something, alors peut-être que le vôtre fonctionne différemment).

2

Vous pouvez appeler bash directement dans votre Makefile au lieu d'utiliser le shell par défaut:

bash -c "ls -al" 

au lieu de:

ls -al 
+0

Notez que 'make' ignore la valeur de la variable d'environnement SHELL. – choroba

4

Si la portabilité est important que vous ne voulez pas dépendre d'une enveloppe spécifique dans votre Makefile. Tous les environnements n'ont pas de bash disponible.

1

Il existe un moyen de le faire sans définir explicitement votre variable SHELL pour pointer vers bash. Cela peut être utile si vous avez beaucoup de makefiles car SHELL n'est pas hérité par les makefiles suivants ou provient de l'environnement. Vous devez également être sûr que toute personne qui compile votre code configure son système de cette façon.

Si vous exécutez sudo dpkg-reconfigure dash et que vous répondez 'non' à l'invite, votre système n'utilisera pas le tiret comme shell par défaut. Il pointera alors vers bash (au moins dans Ubuntu). Notez que l'utilisation de dash comme shell de votre système est un peu plus efficace.

+1

Lorsqu'il est appelé sous le nom 'sh', bash s'exécute en mode de compatibilité (' set -o posix'). La fonctionnalité que l'OP tente d'utiliser, la substitution de processus, n'est pas disponible dans ce mode. –