bash / debian: comportamento estranho do makefile

5

Eu uso um makefile muito simples com o TeX:

test-makefile:
    echo '\newcommand{\seance}{seance1}' > seances/seance.tex

Eu corro:

$ make test-makefile 
echo '\newcommand{\seance}{seance1}' > seances/seance.tex

Meu problema é que o arquivo criado na pasta chamada "seances" não contém os dois primeiros caracteres que ele deve conter:

 
ewcommand{\seance}{seance1}

A primeira linha está vazia.

Claro que posso proteger a primeira anti-flash: echo '\newcommand{\seance}{seance1} , etc. Mas no mundo real isso não funciona: meus makefiles reais (eu publiquei um ECM) não funcionam.

O que acontece? Como pode o bash / debian entender mal o começo do comando?

A propósito:

$ bash --version
GNU bash, version 4.4.19(1)-release (x86_64-pc-linux-gnu)
 
$ cat /etc/debian_version
buster/sid
 
$ uname -a
Linux giljourdan 4.16.0-1-amd64 #1 SMP Debian 4.16.5-1 (2018-04-29) x86_64 GNU/Linux
    
por Pathe 06.06.2018 / 18:38

2 respostas

12

Seu echo é um daqueles que interpreta escapes de barra invertida . Um \n significa uma nova linha, então você consegue exatamente isso. A última barra invertida vem como está, pois \s não é um código de escape válido.

Make executa os comandos através de um shell, usando /bin/sh por padrão, e no Debian isso é traço. O echo incorporado do Dash processa barras invertidas. Bash não faz isso. (E nem o /bin/echo externo no Debian, nem que isso importe, a menos que você execute explicitamente /bin/echo ).

Sua melhor aposta é usar printf explicitamente, pelo menos é seguro, pois sempre processa escapes com barra invertida. O abaixo deve sempre fazer a mesma coisa, o \n no início produz uma barra invertida real e um n , o \n depois produz uma nova linha para terminar a linha.

foo:
        printf '\newcommand\n' > foo

(ou, se você quiser evitar o processamento de barras invertidas, use printf "%s" '\newcommand' )

Veja a pergunta Por que printf é melhor que echo? para mais detalhes sobre echo gotchas.

    
por 06.06.2018 / 18:54
-5

Seu echo é compatível com POSIX e expande escapes de barra invertida C. Isso é mais provável porque /bin/sh é dash em vez de bash.

Há uma correção simples: adicione outra barra invertida para citar a barra invertida:

 test-makefile:
        echo '\newcommand{\seance}{seance1}' > seances/seance.tex

Observe que o padrão POSIX marca a saída de barra invertida C para echo uma , mas o autor do conjunto de testes de conformidade POSIX afirma que é necessário estar em conformidade com XSI para ser POSIX compatível, exceto quando você deseja certificar apenas um sistema pequeno para uso incorporado.

Como não parece que a pergunta original tenha sido solicitada por um pequeno sistema embarcado, esse sistema precisaria implementar extensões XSI para estar em conformidade.

Observe que bash em plataformas com certificação POSIX, como Solaris e Mac OS, é compilado de maneira que ele é compatível com echo por padrão. Portanto, o problema que o bash não é compatível com POSIX XSI por padrão é específico do Linux.

    
por 06.06.2018 / 19:07

Tags