Como escrever exatamente os scripts do bash nos Makefiles?

3

Eu adoro digitar scripts bash, mas se eu preparar vários programas, o diretório raiz do projeto é preenchido com muitos scripts de shell.

É por isso que eu prefiro usar o Makefile.

Makefile é bom. Mas eu quero construir meus makefiles exatamente como scripts normais de bash.

Por exemplo:

Acho que escrevi um script muito rapidamente com o seguinte conteúdo:

#!/bin/bash
echo "hello"
cd ~
do-some-work.sh my-parameter

Eu posso executar este script com $ ./my-important-task.sh .

Se eu quisesse mover esse script para makefile, deveria fazer o seguinte:

SHELL := /bin/bash 

my-important-task: 
    echo "hello" ;\
    cd ~ ;\
    do-some-work.sh my-parameter

mas quero o seguinte:

my-important-task: 
    [[copy and paste the my-important-task.sh file]]

Existe alguma maneira de fazer isso acontecer?

    
por ceremcem 18.03.2016 / 21:59

3 respostas

5

Se você realmente quer "escrever exatamente scripts bash em Makefiles", então você precisará fazer isso um pouco indiretamente. Se você acabou de colar o script após a linha de destino, você terá dois problemas que não podem ser ignorados: as linhas de comando precisam ser recuadas com uma tabulação e os cifrões precisam ser escapados.

Se você usa o GNU make (ao contrário do BSD make, Solaris make, etc.), então você pode definir seu script como uma variável usando o sintaxe de definição de várias linhas e, em seguida, use o value function para usar o valor bruto da variável, ignorando a expansão.

Além disso, conforme explicado por skwllsp , você precisa informar ao make para executar a lista de comandos para cada destino como um script de shell único em vez de linha por linha, o que você pode fazer no GNU make por definindo um .ONESHELL target .

define my_important_task =
# script goes here
endef

my-important-task: ; $(value my_important_task)

.ONESHELL:
    
por 18.03.2016 / 23:29
4

link

If the .ONESHELL special target appears anywhere in the makefile then all recipe lines for each target will be provided to a single invocation of the shell.

Você ainda precisará inserir um caractere de tabulação no início de cada linha e duplicar todos os sinais de dólar (ou seja, substituir $ por $$ em todos os lugares no script).

    
por 18.03.2016 / 22:09
2

Se o problema é que seu diretório de projeto de nível superior está repleto de dezenas de scripts, a solução óbvia é criar um subdiretório (por exemplo, chamado scripts ) para colocá-los.

Execute-os como ./scripts/scriptname e / ou adicione o diretório de scripts ao seu PATH.

Se você ainda quiser que um Makefile execute-os, basta criar entradas Makefile que executam ./scripts/scriptname para esses destinos. por exemplo,

my-important-task: 
    ./scripts/my-important-task.sh my-parameter

NOTA: Se os scripts em ./scripts chamarem outros scripts no mesmo diretório, eles precisarão especificar o caminho completo para o script ou ter o diretório de scripts no PATH.

    
por 19.03.2016 / 02:35

Tags