
In einer Bash-Eingabeaufforderung kann man „diff“ mithilfe von Pseudodateien ausführen:
diff <(echo test) <(echo test)
Das Hinzufügen in dieser Form zu einem Makefile schlägt fehl:
all:
diff <(echo test) <(echo test)
Der Fehler (Hinweis: /bin/sh verweist auf diesem System auf /bin/bash):
/bin/sh: -c: line 0: syntax error near unexpected token `('
/bin/sh: -c: line 0: `diff <(echo test) <(echo test)'
Was bedeutet das und gibt es eine Möglichkeit, zwei Ausgaben dennoch zu vergleichen, ohne temporäre Dateien zu verwenden?
Antwort1
/bin/sh
befindet sich möglicherweise bash
auf Ihrem System, wird aber beim Aufruf als sh
im bash
POSIX-Modus ausgeführt (als ob POSIXLY_CORRECT
es definiert oder mit gestartet worden wäre --posix
).
In diesem Modus gibt es keine Prozessersetzungen.
Lösungen:
Verwenden Sie explizite temporäre Dateien:
all: command1 >tmpfile command2 | diff tmpfile - rm -f tmpfile
Verwenden Sie ein
bash -c
Inline-Skript:all: bash -c 'diff <(command1) <(command2)'
Definieren Sie die Makefile-Variable
SHELL
wie folgt/bin/bash
(oder entsprechend dem Pfadbash
auf Ihrem System):SHELL=/bin/bash
Wenn Sie Portabilität wünschen, wählen Sie die erste Lösung. Wenn Sie mit einer Abhängigkeit von einverstanden sind bash
, wählen Sie die zweite. Wenn Sie sich außerdem nicht um Nicht-GNU- make
Implementierungen kümmern müssen, verwenden Sie die dritte.
Bezüglich des Setzens : Der POSIX-Standard besagt, dass ausführbare Dateien in Makefiles mit der C-Bibliotheksfunktion by SHELL
aufgerufen werden sollten . Es gibt keine Garantie dafür, dass diese Funktion die Umgebungsvariable verwendet (tatsächlich wird dies vom Standard nicht empfohlen). Der Standard geht auch ausführlich darauf ein, dass das Setzen der Makefile-Variable keinen Einfluss auf diesystem()
make
SHELL
SHELL
Umgebungsvariable SHELL
make
. In den meisten mir bekannten Implementierungen SHELL
wird jedoch die Makefile-Variable zum Ausführen der Befehle verwendet.
Der Vorschlag indie Begründung für den make
Nutzenist zu verwenden bash -c
:
Das historische
MAKESHELL
Feature und verwandte Features anderermake
Implementierungen wurden weggelassen. In einigen Implementierungen wird es verwendet, um einem Benutzer zu ermöglichen, die Shell zu überschreiben, die zum Ausführen vonmake
Befehlen verwendet werden soll. Das war verwirrend; für ein portablesmake
sollte die Shell vom Makefile-Autor ausgewählt werden. Außerdem kann ein Makefile-Autor nicht die Verwendung einer alternativen Shell verlangen und das Makefile trotzdem als portabel betrachten. Obwohl es möglich wäre, einen Mechanismus zum Angeben einer alternativen Shell zu standardisieren, sind sich vorhandene Implementierungen nicht über einen solchen Mechanismus einig, und Makefile-Autoren können bereits eine alternative Shell aufrufen, indem sie den Shell-Namen in der Regel für ein Ziel angeben; zum Beispiel:
python -c "foo"