我正在编写一个脚本来创建 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
as $@
。所以你可以根据你的情况这样做:
shift; echo -e "\tg++ -ansi -Wall -g -o \$@ $@" >> Makefile