编译C文件的Shell脚本

编译C文件的Shell脚本

我曾经有一个 shell 脚本,可以将目录中的所有 FILE.c 文件编译为 FILE.out

我把它弄丢了,正在尝试重新制作它,并得到以下内容,我知道它非常相似,但不知道我哪里出了问题。

#!/usr/bin/env bash

for i in 'ls *.c'
do
    gcc -g3 -o3 $i -o {$i%.}.out
done

答案1

您不需要运行该命令ls *.c。 Bash 会自动为您扩展通配符模式。因此,如果您完全绝望并且不想创建 Makefile,您可以这样做:

#!/usr/bin/env bash

for i in *.c
do
    echo "gcc -g3 -o3 $i -o ${i%.c}.out"
    # gcc -g3 -o3 "$i" -o "${i%.c}.out"
done

例子

假设我有这个样本数据:

$ ls -1
a.c
b.c
c.bash
c.c
d.c
e.c

运行我的脚本c.bash

$ ./c.bash 
gcc -g3 -o3 a.c -o a.out
gcc -g3 -o3 b.c -o b.out
gcc -g3 -o3 c.c -o c.out
gcc -g3 -o3 d.c -o d.out
gcc -g3 -o3 e.c -o e.out

要使脚本运行,您需要注释掉echo上面的行,然后取消注释该gcc行。

答案2

具体看你的问题,“你出错的地方”似乎在你的参数扩展中。我认为您在此处命名输出文件时试图更改 i 的值:

{$i%.} 

我想你把美元符号放错地方了。你的意思可能是:

${i%.}

尽管诚实地说,这只会删除“。”从原始文件名。而“filename.c”将产生“filenamec.out”。您可能想要:

${i%.*}

这将产生“filename.out”。此参数扩展语法转换为非贪婪删除以“.”开头的所有内容。之后。对于贪婪删除,语法为:

${i%%.*}

我希望这能更好地回答您的问题,因为它与您的代码相关。

答案3

您的 for 循环for i in 'ls *.c'遍历字符串“ ls *.c”,而不是您想要的输出命令。可以使用命令替换运算符(例如for i in $(ls *.c); do...)来修复此问题,但正如 slm 指出的那样在他的回答中该命令根本不是必需的,因为您可以在 for 循环中使用 shell 通配符的输出:)

整个问题也可以通过一个简单的 makefile 得到更正确的解决:

CC = gcc
CFLAGS = -std=c99 -pedantic -D_XOPEN_SOURCE=600 -Wall -Werror -g
RM = rm -f
SRCS = $(wildcard *.c)
PROGS = $(patsubst %.c,%,$(SRCS))

.PHONY: all clean

all: $(PROGS)

%: %.c
    $(CC) $(CFLAGS) -g3 -o3 -o $@ $<

clean:
    $(RM) $(PROGS)

另存为“Makefile”,运行make。通过运行删除已编译的程序(干净)make clean。 (部分来源于马丁

相关内容