Script 'for loop' não funciona como pretendido

0

Estou escrevendo um script para criar um Makefile. Eu usei um loop para iterar todos os meus argumentos para "echo ... > > Makefile 'na seção de comando de cada destino. O resultado esperado é algo assim:

$ makemake.sh a.out -Hello -World
$ cat Makefile

> a.out : appointment.o calendar.o day.o dayofweek.o time.o year.o 
>   g++ -ansi -Wall -g -o a.out -Hello -World

No entanto, usando a técnica acima:

echo -n "g++ -ansi -Wall -g -o " >> Makefile
  for arg in $@; do
    echo -n "$@ " >> Makefile
  done 

Produz o seguinte:

a.out : appointment.o calendar.o day.o dayofweek.o time.o year.o 
    g++ -ansi -Wall -g -o a.out -Hello -World a.out -Hello -World a.out -Hello -World 

Meu professor recomendou que eu usasse shift, mas isso tornaria mais difícil lembrar argumentos para outros alvos.

Por que isso está acontecendo e o que posso fazer? Embora eu ainda busque uma resposta, estou muito interessado na lógica por trás dessa reação.

    
por darylnak 20.04.2017 / 03:45

2 respostas

2

Seu código tem vários problemas.

  • Você está circulando em arg , mas dentro do loop você se refere a "$@" , não a "$arg" . (Isto é, obviamente, o que causa a saída problemática que você observa.)
  • Sua saída precisa conter uma guia no início para que a linha de ação seja uma sintaxe válida do Makefile.
  • Você não está citando corretamente "$@" na linha for .

Mas, além disso, seu código também é desnecessariamente complexo. Tente isso.

printf '\tg++ -ansi -Wall -g -o' >>Makefile
printf ' %s' "$@" >>Makefile

Por acaso, se isso estiver acontecendo dentro de uma estrutura de controle de algum tipo, é provavelmente mais eficiente e mais elegante redirecionar apenas uma vez. Cada redirecionamento faz com que o arquivo seja aberto e fechado separadamente e, muitas vezes, o fluxo é mais fácil se você puder gravar apenas uma vez, independentemente de o arquivo de saída já existir.

if things are as you wish them to be; then
    execute code which generates output
fi >Makefile
    
por 20.04.2017 / 04:41
2

Em make , você pode consultar o target as $@ . Então você pode fazer isso no seu caso:

shift; echo -e "\tg++ -ansi -Wall -g -o \$@ $@" >> Makefile
    
por 20.04.2017 / 06:28

Tags