編譯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。 (部分來自馬丁

相關內容