
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 echo
linha acima e descomentá- gcc
la.
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)