
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 echo
obige Zeile auskommentieren und die Kommentierung der gcc
Zeile 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)