GNU'daki önkoşullar olarak HTTP'deki dosyaları nasıl kullanabilirim?


10

World Wide Web'deki dosyaları makefiles'imde ön koşul olarak kullanmak istiyorum:

local.dat: http://example.org/example.gz
    curl -s $< | gzip -d | transmogrify >$@

Sadece uzak dosya gibi, yerel dosyadan daha yeniyse "şeklini değiştirmek" isteyen markası normal çalışır.

Ben do not önbelleğe alınmış bir kopyasını tutmak istiyorum example.gz dosyaları büyüktür, ben ham veri gerekmez -. Tercihen dosyayı indirmekten kaçınmak isterim. Amaç -jmarka yapım bayrağını kullanarak bunlardan birkaçını paralel olarak işlemektir.

Bunu çözmenin temiz bir yolu nedir? Gitmek için birkaç yol düşünebilirim:

  • Hedef her yeniden oluşturulduğunda boş bir kukla dosyayı saklayın, güncelleyin
  • GNU make'in yeni eklenti sistemini kullanan bazı eklentiler (ki hakkında hiçbir şey bilmiyorum)
  • HTTP sunucularını yerel dosya sistemine bağlayan agnostik bir yol

Daha fazla kazmadan önce, bazı tavsiyeler, tercihen spesifik örnekler istiyorum!

Yanıtlar:


15

Makefile'nizde böyle bir şey deneyin:

.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

(not: bu bir Makefile'dir, bu nedenle girintiler boşluklar değil, sekmelerdir.Tabii ki \, devam çizgilerinde boşluk bırakılmaması da önemlidir - alternatif olarak ters eğik çizgilerden kaçın ve bir uzun yapın, neredeyse okunamayan çizgi)

Bu GNU maketarifi adlı bir dosya ilk kontroller example.gz(biz bunu kullanarak olacak çünkü mevcut -ziçinde curl) ve onu yaratan toucho değilse. Dokunma, 00:00 (mevcut günün 12:00) zaman damgası ile oluşturur.

Ardından , yalnızca son indirilişinden beri değiştirilmişse indirmek için curl's -z( --time-cond) seçeneğini kullanır example.gz. -zgerçek tarih ifadesi veya dosya adı verilebilir. Bir dosya adı verilirse, dosyanın değişiklik zamanını saat koşulu olarak kullanır.

Bundan sonra, local.datyoksa, ondan daha eski olduğu touchgaranti edilen bir zaman damgası kullanarak oluşturur . Bu gereklidir, çünkü bir sonraki komutun mtime zaman damgasını almak için kullanılması gerekir.example.gzlocal.datstat

Daha sonra, eğer example.gzdaha damgası yeni olan local.datbu boru, example.gziçine transmogrifyve çıkış yönlendirir local.dat.

Son olarak, defter tutma ve temizleme işlerini yapar:

  • kısalır example.gz(çünkü dosyanın tamamını değil, yalnızca bir zaman damgası tutmanız gerekir)
  • touches example.gzile aynı zaman damgasına sahip olacak şekildelocal.dat

.PHONY hedefi local.dat, bu adın dosyası zaten mevcut olsa bile , hedefin her zaman yürütülmesini sağlar .

Orijinal versiyonumun işe yaramadığını ve neden olduğunu belirttiği için @Toby Speight'a teşekkürler.

Alternatif olarak, önce dosyayı transmogrifydosya sistemine indirmeden doğrudan aktarmak istiyorsanız :

.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

NOT: bu çoğunlukla test edilmemiştir, bu nedenle sözdiziminin tam olarak doğru olması için bazı küçük değişiklikler gerekebilir. Burada önemli olan, kopyala yapıştır kargo kült çözümü değil yöntemdir.

On yıllardır bu yöntemin varyasyonlarını (yani touchbir zaman damgası dosyası) kullanıyorum make. Çalışıyor ve genellikle kendi bağımlılık çözüm kodumu sh olarak yazmaktan kaçınmama izin veriyor (her ne kadar stat --printf %Yburada benzer bir şey yapmak zorunda kalsam da ).

Herkes bilir makeyazılım derlemek için harika bir araç ... IMO aynı zamanda sistem yöneticisi ve komut dosyası görevleri için çok düşük puanlı bir araçtır.


1
-zBayrak, tabii ki, uzak sunucu kullandığını düşünür If-Modified-Sincebaşlıklarını. Durum böyle olmayabilir. Sunucu kurulumuna bağlı olarak, bunun yerine ETag, Cache-Controlbaşlıkları kontrol ederek veya başlıkları kontrol ederek veya ayrı bir sağlama toplamı dosyasını kontrol ederek (örn. Sunucu a sağlıyorsa sha1sum) bir şey yapmanız gerekebilir .
Bob

Evet öyle. ancak bu olmadan, OP'nin istediği şeyi yapmanın bir yolu yoktur (büyük dosyayı her çalıştırıldığında make, cmpeski ve yeni dosyaları karşılaştırmak veya kullanmak için bir şey kullanarak geçici bir dosyaya indirmek istemiyorsa ve mv newfile oldfilefarklıysa) . BTW, önbellek denetimi üstbilgileri, dosyanın belirli bir süreden daha yeni olup olmadığını bildirmez. sunucu yöneticilerinin belirli bir dosyayı ne kadar süreyle önbelleğe almanızı istediklerini söylerler ve genellikle pazarlama droidleri tarafından web istatistiklerini "iyileştirmek" için önbellek bozan bir uygulama olarak kullanılırlar.
cas

ETag olan ayrı bir sağlama toplamı dosyası olarak bunu yapmanın başka bir yolu. Her şey sunucunun nasıl ayarlandığına bağlıdır. Örneğin, cdimage.debian.org/debian-cd/current/amd64/iso-cd/SHA1SUMS alınabilir ve tam ISO'yu almaya karar vermeden önce değişip değişmediği kontrol edilebilir. ETag, ayrı bir dosya yerine bir başlık kullanarak da aynı şeyi yapar (ve bunun gibi If-Modified-Since, HTTP sunucusunun uygulanmasına dayanır). Cache-Controlbaşka bir yöntem desteklenmiyorsa dosyayı indirmek için son çare seçeneği olurdu - geleceği tahmin etmeye çalıştığından kesinlikle en az doğrudur.
Bob

Muhtemelen, ve ETag/ If-None-Matchveya diğer sağlama toplamları da daha güvenilirdir If-Modified-Since. Her durumda, bu yorumlar sadece cevabın varsayımlarını ortaya koymaya çalışır (yani, -zsunucu desteğini varsayar) - temel yöntem diğer değişiklik kontrol algoritmalarına uyum sağlamak için oldukça kolay olmalıdır.
Bob

1
ETag tabanlı bir çözüm uygulayarak cevap yazmaktan çekinmeyin. Eğer iyiyse, onu değerlendireceğim. ve sonra birisi gelip tüm web sunucularının bir Etag üstbilgisi sağlamadığını gösterecektir :).
cas

1

Diğer bir seçenek ise, yeniden oluşturma işlemlerinin tetiklenip tetiklenmeyeceğini belirlemek için bağımlılık sağlama toplamlarını kullanan bir derleme sistemi kullanmaktır. Gnu Make ile "dokunma" hilesini çok kullandım, ancak dinamik bağımlılıkları belirtebildiğinizde ve değişmeyen dosyalar yeniden oluşturmayı tetiklemediğinde çok daha basit. İşte GoodMake kullanan bir örnek :

#! /usr/local/goodmake.py /bin/sh -se

#! *.date
    # Get the last-modified date
    curl -s -v -X HEAD http://${1%.date} 2>&1 | grep -i '^< Last-Modified:' >$1

#? local.dat
    site=http://example.org/example.gz
    $0 $site.date
    curl -s $site | gzip -d | transmogrify >$1

Bunun yerine, -X HEADcurl'un manpage şunu kullanmanızı önerir -I: "(-X) yalnızca HTTP isteğinde kullanılan gerçek kelimeyi değiştirir, bukle yolunun davranış biçimini değiştirmez. Örneğin, -X HEAD kullanarak uygun bir HEAD isteği yapmak istiyorsanız -I, - head seçeneğini kullanmanız gerekiyor. "
LightStruk
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.