以下で使いたいです。ワールドワイドウェブ私のmakefileの前提条件として:
local.dat: http://example.org/example.gz
curl -s $< | gzip -d | transmogrify >$@
リモートファイルがローカルファイルよりも最新の場合は、「変換」したいと思います。作る通常の操作。
はいいいえキャッシュされたコピーを保存したいです。example.gz- ファイルが大きく、生データは不要です。可能であれば、すべてのファイルをダウンロードしないことをお勧めします。目的は、makeフラグを使用して一部を並列に処理することです-j
。
この問題を解決するためのきれいな方法は何ですか?いくつかの方法を考えることができます。
- 空のダミーファイルを保持し、ターゲットが再生成されるたびに更新します。
- GNU makeを使用するいくつかのプラグイン新しいプラグインシステム(私はこれについて何も知らない)
- ローカルファイルシステムにHTTPサーバーをインストールするための不可知論的な方法
もっと学ぶ前に、いくつかのアドバイス、好ましくは具体的な例を聞きたいです!
ベストアンサー1
Makefileで次のようにしてみてください。
.PHONY: local.dat
local.dat:
[ -e example.gz ] || touch -d '00:00' example.gz
curl -z example.gz -s http://example.org/example.gz -o example.gz
[ -e $@ ] || touch -d 'yesterday 00:00' $@
if [ "$(shell stat --printf '%Y' example.gz)" \
-gt "$(shell stat --printf '%Y' $@)" ] ; then \
zcat example.gz | transmogrify >$@ ; \
fi
truncate -s 0 example.gz
touch -r $@ example.gz
(注:これはMakefileなので、インデントは空白ではなくタブです。もちろん、連続した行に末尾の空白がないか、\
バックスラッシュエスケープを削除してほとんど読みにくい長い行にすることも重要です。)
このGNUmake
レシピは、最初に名前付きファイルがexample.gz
存在することを確認し(で使用されるため)、-z
存在しない場合はcurl
ファイルを生成します。touch
タッチで生成されたタイムスタンプは00:00(当日午前12時)です。
次に、()curl
オプションを使用して、最後のダウンロード以降に変更されたコンテンツのみをダウンロードします。実際の日付表現またはファイル名を指定できます。ファイル名が与えられると、ファイルの修正時間を時間条件として使用します。 -z
--time-cond
example.gz
-z
後で存在しない場合は、保証されたタイムスタンプを使用local.dat
して生成されます。touch
年をとるよりexample.gz
。 mtimeタイムスタンプを取得local.dat
するには、次のコマンドが存在する必要があるため、これが必要ですstat
。
その後、example.gz
タイムスタンプがlocal.dat
それよりも最新の場合は、出力をパイプにexample.gz
リダイレクトします。transmogrify
local.dat
最後に、帳簿とクリーンアップを実行します。
- 切り捨てます
example.gz
(フルファイルではなくタイムスタンプだけを維持すればよいので)。 touch
つまりexample.gz
、同じタイムスタンプを持つことになります。local.dat
.PHONY ターゲットは、local.dat
その名前のファイルがすでに存在していても、ターゲットが常に実行されることを保証します。
元のバージョンが機能していないこと、そしてその理由をコメントで指摘してくれた@Toby Speightに感謝します。
transmogrify
または、まずファイルシステムにダウンロードせずにファイルを直接パイプする場合:
.PHONY: local.dat
local.dat:
[ -e example.gz ] || touch -d '00:00' example.gz
[ -e $@ ] || touch -d 'yesterday 00:00' $@
if [ "$(shell stat --printf '%Y' example.gz)" \
-gt "$(shell stat --printf '%Y' $@)" ] ; then \
curl -z example.gz -s http://example.org/example.gz | transmogrify >$@ ; \
fi
touch -r $@ example.gz
メモ:これはほとんどテストされていないため、構文を完全に変更するには若干の変更が必要な場合があります。ここで重要なのは、コピー貼り付けカーゴカルトソリューションではなくアプローチです。
私は何十年もの間、このアプローチの変形(touch
タイムスタンプファイルなど)を使用してきました。make
それはうまくいき、通常はshで私の依存関係解決コードを書くのを避けることができます(stat --printf %Y
ここでも同様のことをする必要がありましたが)。
make
これがソフトウェアコンパイルのための素晴らしいツールであることは誰もが知っています。私の考えでは、システム管理とスクリプト作業のためのツールとして、深刻に過小評価されたツールでもあります。