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