我曾经有一个 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
。 (部分来源于马丁)