
Em um prompt bash, pode-se executar diff usando pseudoarquivos:
diff <(echo test) <(echo test)
Adicionar isso como está em um Makefile falha:
all:
diff <(echo test) <(echo test)
O erro (dica: /bin/sh aponta para /bin/bash neste sistema):
/bin/sh: -c: line 0: syntax error near unexpected token `('
/bin/sh: -c: line 0: `diff <(echo test) <(echo test)'
O que isso significa e ainda existe uma maneira de diferenciar duas saídas sem usar arquivos temporários?
Responder1
/bin/sh
pode estar bash
no seu sistema, mas quando invocado como sh
, bash
estará rodando no modo POSIX (como se POSIXLY_CORRECT
tivesse sido definido ou iniciado com --posix
).
Neste modo, não existem substituições de processo.
Soluções:
Use arquivos temporários explícitos:
all: command1 >tmpfile command2 | diff tmpfile - rm -f tmpfile
Use um
bash -c
script em linha:all: bash -c 'diff <(command1) <(command2)'
Defina a variável Makefile
SHELL
como/bin/bash
(ou qualquer que seja o caminhobash
em seu sistema):SHELL=/bin/bash
Se você deseja portabilidade, escolha a primeira solução. Se você concorda com a dependência de bash
, escolha a segunda. Se você também não precisa se preocupar com make
implementações não-GNU, use o terceiro.
Em relação à configuração SHELL
: O padrão POSIX diz que os executáveis em Makefiles devem ser invocados com a system()
função da biblioteca C por make
. Não é garantido que esta função use a SHELL
variável de ambiente (na verdade, fazer isso é desencorajado pelo padrão). O padrão também vai longe ao dizer que definir a variável Makefile SHELL
não deve afetar ovariável de ambiente SHELL
. Na maioria das implementações make
que conheço, entretanto, a variável Makefile SHELL
será usada para executar os comandos.
A sugestão ema justificativa para a make
utilidadeé usar bash -c
:
O recurso histórico
MAKESHELL
e os recursos relacionados fornecidos por outrasmake
implementações foram omitidos. Em algumas implementações, é usado para permitir que um usuário substitua o shell a ser usado para executarmake
comandos. Isso foi confuso; para um portátilmake
, o shell deve ser escolhido pelo gravador do makefile. Além disso, um gravador de makefile não pode exigir o uso de um shell alternativo e ainda considerar o makefile portátil. Embora fosse possível padronizar um mecanismo para especificar um shell alternativo, as implementações existentes não concordam com tal mecanismo, e os criadores de makefile já podem invocar um shell alternativo especificando o nome do shell na regra para um destino; por exemplo:
python -c "foo"