脚本“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,您可以参考targetas $@。所以你可以根据你的情况这样做:

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

相关内容