Shell script para compilar arquivos C

Shell script para compilar arquivos C

Eu costumava ter um script de shell que compilava todos os arquivos FILE.c em um diretório para FILE.out

Eu o perdi e estou tentando refazê-lo e tenho o seguinte que sei que é muito semelhante, mas não sei onde estou errando.

#!/usr/bin/env bash

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

Responder1

Você não precisa executar o comando ls *.c. Bash expandirá o padrão curinga para você automaticamente. Então se você está completamente desesperado e não quer fazer um Makefile você pode fazer isso:

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

Exemplo

Digamos que eu tenha estes dados de amostra:

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

Executando meu 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 executar o script, você deve comentar a echolinha acima e descomentá- gccla.

Responder2

Olhando especificamente para sua pergunta, parece que “onde você errou” está na expansão de seus parâmetros. Acho que você estava tentando alterar o valor de i ao nomear o arquivo de saída aqui:

{$i%.} 

Acho que você perdeu o cifrão. Você pode ter querido dizer:

${i%.}

Embora a honestidade só teria removido o “.” do nome do arquivo original. Considerando que “filename.c” teria gerado “filenamec.out”. Você provavelmente quer:

${i%.*}

Isso teria gerado “filename.out”. Esta sintaxe de expansão de parâmetro se traduz em uma exclusão não gananciosa de tudo que começa em “.” e depois. Para exclusão gananciosa, a sintaxe seria:

${i%%.*}

Espero que isso responda melhor à sua pergunta no que se refere ao seu código.

Responder3

Seu loop for for i in 'ls *.c'está fazendo um loop na string literal " ls *.c", não no comando de saída como você pretendia. Isso poderia ser corrigido usando o operador de substituição de comando (por exemplo for i in $(ls *.c); do...), mas como slm apontaem sua respostao comando não é necessário, pois você pode usar a saída do shell globbing no for-loop :)

Todo esse problema também poderia ser resolvido de forma mais adequada com um makefile simples:

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)

Salve como "Makefile", execute make. Remova programas compilados (limpos) executando make clean. (Fonte parcial deMartinho)

informação relacionada