Cファイルをコンパイルするシェルスクリプト

Cファイルをコンパイルするシェルスクリプト

かつてディレクトリ内のすべてのFILE.cファイルをFILE.outにコンパイルするシェルスクリプトがありました。

私はそれを失い、それを再作成しようとしており、次のようになりました。非常に似ていることを知っていますが、どこで間違っているのかわかりません。

#!/usr/bin/env bash

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

答え1

このコマンドを実行する必要はありませんls *.c。 Bashは自動的にワイルドカードパターンを拡張します。したがって、本当に絶望的でMakefileを作成したくない場合は、次のようにすることができます。

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

はい

次のサンプルデータがあるとします。

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

私のスクリプトを実行してください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

スクリプトを実行するには、echo上記の行をコメントアウトしてから、このgcc行のコメントを削除する必要があります。

答え2

あなたの質問を具体的に見ると、「どこで間違っているか」がパラメータ拡張にあるようです。ここで、出力ファイルに名前を付けるときにi値を変更しようとしているようです。

{$i%.} 

ドル記号を間違って見たと思います。おそらく次の意味です。

${i%.}

正直に言うと、元のファイル名から「.」だけが削除されます。そして、「filename.c」は「filenamec.out」を生成します。次のことができます。

${i%.*}

これにより「filename.out」が生成されます。このパラメータ拡張構文は、「.」で始まるすべての項目を無欲なく削除することに変換されます。後。貪欲な削除の場合、構文は次のとおりです。

${i%%.*}

これがあなたのコードに関連し、あなたの質問に良い答えになることを願っています。

答え3

forループは、目的の出力コマンドではなくfor i in 'ls *.c'文字列 ""を繰り返します。これはls *.cコマンド置換演算子(たとえば)を使用して解決できますが、slmが指摘したようにfor i in $(ls *.c); do...彼の答えにforループでシェルワイルドカードの出力を使用できるため、このコマンドはまったく必要ありません。 :)

単純なmakefileを使用すると、問題全体をより正確に解決することもできます。

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)

「Makefile」として保存して実行しますmake。 (clean)を実行してコンパイルされたプログラムを削除しますmake clean。 (部分的に派生男の名前)

関連情報