Script de Shell para compilar archivos C

Script de Shell para compilar archivos C

Solía ​​​​tener un script de shell que compilaba todos los archivos FILE.c en un directorio en FILE.out

Lo perdí y estoy intentando rehacerlo y tengo lo siguiente que sé que es muy similar pero no sé dónde me estoy equivocando.

#!/usr/bin/env bash

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

Respuesta1

No es necesario ejecutar el comando ls *.c. Bash expandirá el patrón comodín automáticamente. Entonces, si estás completamente desesperado y no quieres crear un Makefile, puedes hacer esto:

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

Ejemplo

Digamos que tenía estos datos de muestra:

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

Ejecutando mi script 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

Para ejecutar el script, debe comentar la echolínea anterior y descomentar la gcclínea.

Respuesta2

Mirando específicamente su pregunta, parece que "dónde salió mal" está en la expansión de sus parámetros. Creo que estabas intentando cambiar el valor de i al nombrar el archivo de salida aquí:

{$i%.} 

Creo que perdiste el signo del dólar. Es posible que haya querido decir:

${i%.}

Aunque honestidad eso solo habría eliminado el "." del nombre del archivo original. Mientras que "filename.c" habría dado como resultado "filenamec.out". Probablemente quieras:

${i%.*}

Esto habría producido "nombre de archivo.out". Esta sintaxis de expansión de parámetros se traduce en una eliminación no codiciosa de todo lo que comienza en "." y después. Para una eliminación codiciosa, la sintaxis sería:

${i%%.*}

Espero que esto responda mejor a su pregunta en lo que respecta a su código.

Respuesta3

Su bucle for i in 'ls *.c'for recorre la cadena literal " ls *.c", no el comando de salida como pretendía. Esto podría solucionarse utilizando el operador de sustitución de comandos (por ejemplo for i in $(ls *.c); do...), pero como señala slmen su respuestael comando no es necesario en absoluto ya que puede usar la salida del shell globbing en el bucle for :)

Todo este problema también podría resolverse mejor con un simple archivo MAKE:

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)

Guárdelo como "Makefile", ejecute make. Elimine los programas compilados (limpios) ejecutando make clean. (Fuente parcial deMartín)

información relacionada