2016-02-19 7 views
5

क्या कोई जानता है कि नुस्खा पर यहां दस्तावेज़-दस्तावेज़ पुनर्निर्देशन का उपयोग कैसे करें?मेकफ़ाइल रेसिपीर यहां एक दस्तावेज़-दस्तावेज़ पुनर्निर्देशन

test: 
    sh <<EOF 
    echo I Need This 
    echo To Work 
    ls 
    EOF 

मैं किसी भी समाधान हमेशा की तरह बैकस्लैश विधि (जो मूल रूप से एक पंक्ति में एक आदेश के साथ समाप्त होता है) की कोशिश कर रहा नहीं मिल रहा।

दलील:

मैं बहु लाइन व्यंजनों है कि मैं एक और आदेश के माध्यम से प्रॉक्सी करना चाहते हैं (उदाहरण के लिए, श, डोकर) का एक सेट है।

onelinerecipe := echo l1 
define twolinerecipe := 
echo l1 
echo l2 
endef 
define threelinerecipe := 
echo l1 
echo l2 
echo l3 
endef 

# sh as proxy command and proof of concept 
proxy := sh 

test1: 
    $(proxy) <<EOF 
    $(onelinerecipe) 
    EOF 

test2: 
    $(proxy) <<EOF 
    $(twolinerecipe) 
    EOF 

test3: 
    $(proxy) <<EOF 
    $(threelinerecipe) 
    EOF 

समाधान मैं बचाना पसंद करूंगा: मल्टीलाइन मैक्रोज़ को एकल लाइनों में परिवर्तित करें।

define threelinerecipe := 
echo l1; 
echo l2; 
echo l3 
endef 

test3: 
    $(proxy) <<< "$(strip $(threelinerecipe))" 

यह काम करता है (मैं मेकअप के खोल के रूप में gmake 4.0 और पार्टी का उपयोग करें) लेकिन यह मेरी व्यंजनों को बदलने की आवश्यकता है और मैं एक बहुत कुछ है। पट्टी मैक्रो से नई लाइनों को हटा देती है, तो सब कुछ एक ही पंक्ति में लिखा जाता है।

मेरे अंतिम लक्ष्य है: proxy := docker run ...

+0

sh -c '' अपने आदेश यहां कैसे रखें 'के बारे में कैसे? – fanton

+0

[मेकफ़ाइल में हेरेडोक का संभावित डुप्लिकेट?] (Http://stackoverflow.com/questions/5873025/heredoc-in-a-makefile) – e0k

+0

@ e0k मैंने संदर्भ जोड़ा –

उत्तर

5

अपने Makefile में लाइन .ONESHELL: का उपयोग करते हुए कहीं एक भी खोल मंगलाचरण के लिए सभी नुस्खा लाइनों भेज देंगे, आप अपने मूल Makefile अपेक्षा के अनुरूप काम करता है खोजना चाहिए।

+1

महत्वपूर्ण अनुपलब्ध नोट्स: इसका प्रभाव वैश्विक है और एक नियम और नुस्खा के लिए स्थानीय नहीं है। यदि यह मेकफ़ाइल में कहीं भी दिखाई देता है तो ** प्रत्येक ** लक्ष्य के लिए ** सभी ** नुस्खा लाइन ** खोल के एक ही आमंत्रण के लिए प्रदान की जाएगी। यह मेरे मामले में समस्याएं पेश नहीं करता है। लेकिन यह भी ध्यान दें कि त्रुटि को छोड़ने के डिफ़ॉल्ट व्यवहार को रखने के लिए '.SHELLFLAGS = -ec' आवश्यक है। –

+1

मैं कुछ दिनों से इस समाधान का उपयोग कर रहा हूं और अब तक की एकमात्र कमी जो मुद्दों को गूंज रही है। क्योंकि 'ONESHELL: 'के साथ, अग्रणी' @ 'अब संपूर्ण नुस्खा के लिए मान्य है। यह चुनिंदा गूंज बनाता है (एक आदेश गूंजता है और दूसरा नहीं) अब संभव नहीं है। इसे हल करने के लिए, आप केवल अपनी नुस्खा बदल सकते हैं, इस प्रकार एक नियम तोड़ना जिसे मैं ढूंढ रहा था: प्रॉक्सी पारदर्शी रूप से। वैसे भी, यह एकमात्र समाधान है जो यहां-डॉक्टर को अनुमति देता है, इसलिए मैं इसे मान्य कर रहा हूं। –

3

बनाने जब एक नुस्खा (अर्थात, लाइनों के एक ब्लॉक सभी \ में समाप्त होने के अलावा पिछले से), पास कर देता है कि ब्लॉक खोल करने के लिए संयुक्त राष्ट्र-modifed में एक बहु लाइन ब्लॉक देखता है। यह आम तौर पर यहां दस्तावेज़ों के अलावा बैश, में काम करता है। इस के आसपास

एक तरह से तो अवांछित \ रों पट्टी है, तो बैश के eval के परिणामस्वरूप स्ट्रिंग गुजरती हैं। आप में और ${SHELL} के साथ खेलकर बनाते हैं। यदि आप केवल कुछ लक्ष्यों के लिए इसे लात मारना चाहते हैं तो आप इन दोनों को लक्ष्य-विशिष्ट रूप में उपयोग कर सकते हैं।

.PHONY: heredoc 

heredoc: .SHELLFLAGS = -c eval 
heredoc: SHELL = bash -c 'eval "$${@//\\\\/}"' 

heredoc: 
    @echo First 
    @cat <<-there \ 
     here line1 \ 
     here anotherline \ 
    there 
    @echo Last 

$ make 
First 
here line1 
here anotherline 
Last 

के हवाले से, यूजीन उस के साथ सावधानी से दे रही है। यहां धोखा दें: मैं सभी बैकस्लैश को हटा रहा हूं, लाइन के सिरों पर नहीं। वाईएमएमवी।

+0

विशेष रूप से, "जब मेकअप एक नुस्खा में एक बहु-लाइन ब्लॉक देखता है (यानी, आखिरी के अलावा \" में समाप्त होने वाली रेखाओं का एक ब्लॉक देखता है, तो यह उस ब्लॉक को खोल में अन-संशोधित करता है। " बिट: मैंने यहां एक-डॉक का उपयोग करने की कोशिश की है जहां इसे अकेले उस तकनीक से हल किया जाता है। – kostix