スクリプト「forループ」が期待どおりに機能しません。

スクリプト「forループ」が期待どおりに機能しません。

Makefileを生成するスクリプトを作成しています。 forループを使用して、「echo ... >> Makefile」のすべてのパラメータを各ターゲットのコマンドセクションとして繰り返しました。予想される出力は次のとおりです。

$ 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

しかし、上記の技術を使用すると、次のようになります。

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

次の結果が生成されます。

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 

教授はコンバージョンを使用するよう提案しましたが、これを行うと、他の目標に対する主張を覚えにくくなります。

なぜこれが起こるのですか?どうですか?私はまだ答えを探していますが、この反応の後ろに隠されたロジックに非常に興味があります。

答え1

コードにはいくつかの問題があります。

  • ループしているがループ内ではなくarg参照ループ内にあります。 (明らかにこれがあなたが観察した問題のある出力の原因です。)"$@""$arg"
  • タスク行が有効なMakefile構文になるには、出力の先頭にタブ文字を含める必要があります。
  • "$@"その行forから正しく引用されていません。

しかし、それ以上にコードは不必要に複雑です。この試み。

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

ところで、これがいくつかの制御構造内で発生した場合、一度だけリダイレクトする方が効率的でエレガントです。各リダイレクトにより、ファイルが別々に開閉され、通常は出力ファイルがすでに存在するかどうかにかかわらず、一度だけ書き込むとプロセスが簡単になります。

if things are as you wish them to be; then
    execute code which generates output
fi >Makefile

答え2

make参照できます。したがって、状況に応じて次のようにすることができます。target$@

shift; echo -e "\tg++ -ansi -Wall -g -o \$@ $@" >> Makefile

関連情報