
我曾經有一個 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
。 (部分來自馬丁)