मैं GNU बनाने में किसी और चीज की HTTP से फ़ाइलों का उपयोग कैसे कर सकता हूं?


10

मैं अपने मेकफाइल्स में किसी और चीज के रूप में वर्ल्ड वाइड वेब की फाइलों का उपयोग करना चाहता हूं:

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

मैं केवल "परिणत हो जाना" के लिए करता है, तो रिमोट फाइल स्थानीय फ़ाइल से अधिक नया है, जैसे चाहते हैं कर सामान्य रूप से चल रही है।

मैं example.gz की कैश्ड कॉपी नहीं रखना चाहता - फाइलें बड़ी हैं, और मुझे कच्चे डेटा की आवश्यकता नहीं है। अधिमानतः मैं फ़ाइल को डाउनलोड करने से बचना चाहता हूँ। लक्ष्य मेक फ्लैग का उपयोग करके इनमें से कुछ को समानांतर में संसाधित करना है।-j

इसे हल करने का एक साफ तरीका क्या है? मैं जाने के लिए कुछ तरीके सोच सकता हूं:

  • एक खाली डमी फ़ाइल को दूर रखें, हर बार लक्ष्य के पुन: निर्मित होने पर अपडेट किया जाता है
  • GNU मेकिंग के नए प्लगइन सिस्टम का उपयोग करने वाले कुछ प्लगइन (जिसके बारे में मुझे कुछ नहीं पता)
  • एक मेक-एग्नॉस्टिक तरीका जो स्थानीय फाइलसिस्टम में HTTP सर्वरों की गणना करता है

आगे खुदाई करने से पहले, मैं कुछ सलाह चाहता हूँ, अधिमानतः विशिष्ट उदाहरण!

जवाबों:


15

अपने 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

(ध्यान दें: यह एक मेकफाइल है, इसलिए इंडेंट टैब हैं, स्पेस नहीं। बेशक, यह भी महत्वपूर्ण है कि \कंटीन्यूअस लाइन्स के बाद कोई स्पेस न हो - वैकल्पिक रूप से बैकस्लैश-एस्केप से छुटकारा पाएं और एक लंबे समय तक करें, लगभग-अप्राप्य रेखा)

यह जीएनयू makeनुस्खा पहले जांच करता है कि एक फ़ाइल कहा जाता है example.gzमौजूद है (क्योंकि हम साथ इसे का उपयोग करने जा रहे हैं -zमें curl), और साथ यह बनाता है touch, तो ऐसा नहीं है। स्पर्श इसे 00:00 (वर्तमान दिन के 12 बजे) के टाइमस्टैम्प के साथ बनाता है।

तो फिर यह का उपयोग करता curlहै -z( --time-cond) केवल डाउनलोड करने का विकल्प example.gzहै, तो यह पिछली बार इसे डाउनलोड किया गया था के बाद से संशोधित किया गया है। -zएक वास्तविक दिनांक अभिव्यक्ति, या फ़ाइल नाम दिया जा सकता है। यदि फ़ाइल नाम दिया गया है, तो यह समय की स्थिति के रूप में फ़ाइल के संशोधन समय का उपयोग करेगा।

उसके बाद, यदि local.datवह मौजूद नहीं है, तो यह उस समय से पुरानेtouch होने की गारंटी वाले टाइमस्टैम्प का उपयोग करके बनाता है । यह आवश्यक है क्योंकि अगले आदेश के लिए इसका माइम टाइमस्टैम्प प्राप्त करने के लिए मौजूद होना आवश्यक है ।example.gzlocal.datstat

फिर, अगर 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। यह काम करता है, और आमतौर पर मुझे अपने स्वयं के निर्भरता रिज़ॉल्यूशन कोड को श में लिखने से बचने की अनुमति देता है (हालांकि मुझे stat --printf %Yयहां कुछ ऐसा ही करना पड़ा है)।

हर कोई जानता makeहै कि सॉफ्टवेयर को संकलित करने के लिए एक महान उपकरण है ... IMO यह सिस्टम व्यवस्थापक और स्क्रिप्टिंग कार्यों के लिए बहुत कम रेटेड उपकरण है।


1
-zझंडा, ज़ाहिर है, यह मानता है कि दूरस्थ सर्वर का उपयोग करता है If-Modified-Sinceहेडर। जरूरी नहीं कि ऐसा ही हो। सर्वर सेटअप के आधार पर, आपको इसके बजाय हेडर की ETagजाँच करके Cache-Control, या एक अलग चेकसम फ़ाइल (जैसे कि सर्वर प्रदान करता है sha1sum) की जाँच करके कुछ करने की आवश्यकता हो सकती है ।
बॉब

हाँ यह करता है। लेकिन इसके बिना, ओपी क्या चाहता है, ऐसा करने का कोई तरीका नहीं है (जब तक कि वह हर बार चलने वाली पुरानी फ़ाइल को एक अस्थायी फ़ाइल में डाउनलोड करने के लिए तैयार नहीं होता है make, cmpपुरानी या नई फ़ाइलों की तुलना करने के लिए उपयोग, या कुछ और mv newfile oldfileअगर वे अलग हैं) । BTW, कैश-कंट्रोल हेडर आपको यह नहीं बताते हैं कि फ़ाइल किसी दिए गए समय से नई है या नहीं। वे आपको बताते हैं कि कब तक सर्वर मानते हैं कि आप किसी दिए गए फ़ाइल को कैश करना चाहते हैं - और इसका उपयोग अक्सर अपने वेब आंकड़ों को "सुधार" करने के लिए कैश-बस्टिंग अभ्यास के रूप में ड्रॉइड का उपयोग करते हैं।
कैस

ETag इसे करने का एक और तरीका है, जैसा कि एक अलग चेकसम फाइल है। यह सब इस बात पर निर्भर करता है कि सर्वर कैसे सेट होता है। उदाहरण के लिए, एक लाने सकता है cdimage.debian.org/debian-cd/current/amd64/iso-cd/SHA1SUMS और देखें कि क्या यह पूर्ण आईएसओ लाने के लिए निर्णय लेने से पहले बदल गया है। ETag एक ही काम करता है, एक अलग फ़ाइल के बजाय हेडर का उपयोग करना (और, जैसे If-Modified-Since, इसे लागू करने वाले HTTP सर्वर पर निर्भर करता है)। Cache-Controlयदि कोई अन्य विधियाँ समर्थित नहीं हैं, तो फ़ाइल को डाउनलोड करने का एक अंतिम उपाय विकल्प होगा - यह निश्चित रूप से सबसे कम सटीक है क्योंकि यह भविष्य की भविष्यवाणी करने की कोशिश करता है।
बॉब

यकीनन, ETag/ If-None-Matchऔर अन्य चेकसम की तुलना में अधिक विश्वसनीय If-Modified-Sinceहैं। किसी भी स्थिति में, ये टिप्पणियां केवल उत्तर की मान्यताओं (अर्थात्, -zसर्वर समर्थन मानती हैं) को बाहर करने की कोशिश करती हैं - मूल विधि को अन्य परिवर्तन-जाँच एल्गोरिदम के अनुकूल होने के लिए काफी आसान होना चाहिए।
बॉब

1
ईटाग पर आधारित समाधान को लागू करने के लिए उत्तर लिखने के लिए स्वतंत्र महसूस करें। अगर यह किसी भी अच्छा है, मैं इसे बढ़ा दूंगा। और फिर कोई साथ आएगा और इंगित करेगा कि सभी वेब सर्वर एक Etag हेडर नहीं प्रदान करते हैं :)।
कैस

1

एक अन्य विकल्प बिल्ड सिस्टम का उपयोग करना है जो यह निर्धारित करने के लिए निर्भरता चेकसम का उपयोग करता है कि क्या फिर से ट्रिगर करना है। मैंने ग्नू मेक के साथ "टच" ट्रिक का उपयोग किया है, लेकिन यह बहुत सरल है जब आप डायनेमिक निर्भरता को निर्दिष्ट कर सकते हैं और जब फाइलें नहीं बदलती हैं, तो यह ट्रिगर को ट्रिगर नहीं करता है। यहाँ GoodMake का उपयोग करके एक उदाहरण दिया गया है :

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

इसके बजाय -X HEAD, कर्ल के मैनपेज का उपयोग करने की सिफारिश की जाती है -I: "(-X) केवल HTTP अनुरोध में उपयोग किए जाने वाले वास्तविक शब्द को बदल देता है, यह कर्ल के व्यवहार के तरीके को नहीं बदलता है। इसलिए उदाहरण के लिए यदि आप एक उचित HEAD अनुरोध करना चाहते हैं, तो -X पैड का उपयोग करें। पर्याप्त नहीं होगा। आपको -I, - हेड ऑप्शन का उपयोग करना होगा। "
लाइटस्ट्रेक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.