Shell-Skript zum Kompilieren von C-Dateien

Shell-Skript zum Kompilieren von C-Dateien

Früher hatte ich ein Shell-Skript, das alle FILE.c-Dateien in einem Verzeichnis in FILE.out kompilierte

Ich habe es verloren und versuche, es neu zu erstellen. Dabei habe ich Folgendes erhalten, von dem ich weiß, dass es sehr ähnlich ist, aber ich kann nicht sagen, was ich falsch mache.

#!/usr/bin/env bash

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

Antwort1

Sie müssen den Befehl nicht ausführen ls *.c. Bash erweitert das Platzhaltermuster automatisch für Sie. Wenn Sie also völlig verzweifelt sind und kein Makefile erstellen möchten, können Sie Folgendes tun:

#!/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

Beispiel

Angenommen, ich hätte diese Beispieldaten:

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

Ausführen meines Skripts 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

Um das Skript auszuführen, müssen Sie die echoobige Zeile auskommentieren und die Kommentierung der gccZeile aufheben.

Antwort2

Wenn man sich Ihre Frage genauer ansieht, scheint es, dass Ihr Fehler in der Parametererweiterung liegt. Ich glaube, Sie haben versucht, den Wert von i zu ändern, als Sie die Ausgabedatei hier benannt haben:

{$i%.} 

Ich glaube, Sie haben das Dollarzeichen falsch platziert. Vielleicht haben Sie gemeint:

${i%.}

Ehrlich gesagt hätte das aber nur den „.“ aus dem ursprünglichen Dateinamen entfernt. „filename.c“ hätte hingegen „filenamec.out“ ergeben. Sie möchten wahrscheinlich:

${i%.*}

Dies hätte „filename.out“ ergeben. Diese Parametererweiterungssyntax führt zu einer nicht gierigen Löschung von allem, was bei „.“ beginnt und danach folgt. Für eine gierige Löschung wäre die Syntax:

${i%%.*}

Ich hoffe, dies beantwortet Ihre Frage in Bezug auf Ihren Code besser.

Antwort3

Ihre For-Schleife for i in 'ls *.c'durchläuft die Literalzeichenfolge " ls *.c" und nicht den Ausgabebefehl, wie Sie es beabsichtigt haben. Dies könnte durch die Verwendung des Befehlssubstitutionsoperators (z. B. for i in $(ls *.c); do...) behoben werden, aber wie slm anmerktin seiner Antwortder Befehl ist überhaupt nicht notwendig, da Sie die Ausgabe des Shell-Globbings in einer For-Schleife verwenden können :)

Dieses ganze Problem könnte auch mit einem einfachen Makefile besser gelöst werden:

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)

Als "Makefile" speichern, ausführen make. Kompilierte Programme entfernen (bereinigen) durch Ausführen von make clean. (Teilweise Quellcode durchMartin)

verwandte Informationen