web-dev-qa-db-fra.com

Makefile `echo -n 'ne fonctionne pas

J'essaie d'avoir mon texto de makefile Echo sans la nouvelle ligne de fuite, mais je ne peux pas. Je ressens le comportement sur OS X (sur Linux Tout fonctionne comme prévu).

Faire jouer

a:
    @echo -n "hello"

b:
    @echo -n hello

c:
    @/bin/echo -n "hello"

Sortir:

$make a
-n hello
$make b
hello$make c
hello$

En d'autres termes, le make a est cassé. Qu'est-ce qui se passe exactement? Est-ce que vous faites utiliser un écho intégré? Clairement, la présence des citations doubles change le comportement, mais pourquoi?

Mettre à jour

Comme découvert par @cheppner, en utilisant le chemin complet de /bin/echo Dans le makefile comprend correctement le drapeau -n.

27
Chris

Quelque chose sur les citations confonds make. Votre code se comporte la même chose pour moi, mais ce qui suit fonctionne comme prévu:

help:
        @echo -n Shouldn\'t print a newline

Code papier Le chemin d'accès à l'exécutable fonctionne également:

help:
        @/bin/echo -n "Shouldn't print a newline"

La page Mac OS X Man pour echo, tout en discutant de l'existence de Shell intégré echos, mentionne que le echo de sh(1) ne prend pas en charge L'option -n, mais cela ne veut pas expliquer (à moi, de toute façon) pourquoi ma première alternative fonctionne.


Confirmation que make utilise sh pour exécuter les commandes par défaut. Dans

Shell = bash
help:
        @echo -n "Shouldn't print a newline"
        @echo -n Shouldn\'t print a newline

les deux déclarations d'écho se comportent de la même manière (pas de nouvelles lignes imprimées). Donc, sans cette variable, nous avons bash prétendant être sh, mais évaluer les deux lignes différemment. Question 1: Pourquoi? Question 2: La deuxième ligne est-elle l'autochtone bash _ écho ou /bin/echo, Plutôt que l'émulation sh _ echo?

18
chepner

Le problème vient de l'interaction malheureuse de deux faits.

Premièrement, make a deux modes d'opérations en fonction de la complexité de la recette à exécuter:

  • Si la commande est facile, make exécutera directement la recette avec ses commandes intégrées. C'est ce qui se passe dans votre cas b.
  • Si la commande est complexe, make _ va frayer une coquille pour interpréter et exécuter la recette. C'est ce qui se passe dans votre cas a.

Deuxièmement, make utilise /bin/sh comme une coquille mais la fonctionnalité de /bin/sh est implémenté différemment sur Mac OS X et Linux:

  • Sur Mac OS X, la fonctionnalité de /bin/sh est mis en œuvre par bash. Également sur Mac OS X, bash est compilé avec --enable-strict-posix-default. Une conséquence de ce drapeau est que la commande echo ne comprend pas le -n drapeau.
  • Sur Linux, la fonctionnalité de /bin/sh est mis en œuvre par dash qui est moins strict par rapport à la spécification de POSIX. Donc le drapeau -n est implémenté dans la commande echo.

BTW, le makefile Buitlin echo commande comprend le -n Drapeau qui explique pourquoi le cas b fonctionne toujours.

La manière propre et portable de résoudre votre problème est de remplacer votre @echo -n recettes avec @printf recettes.

24
Nicolas Dudebout

eCHO est une coquille BASH, mais lorsque vous l'exécutant de Makefile, c'est la version du programme

3
pizza