जीएनयू मेकफाइल्स में प्रक्रिया प्रतिस्थापन


11

बैश प्रॉम्प्ट पर, कोई भी छद्म फ़ाइलों का उपयोग करके अलग-अलग निष्पादित कर सकता है:

diff <(echo test) <(echo test)

इसे Makefile में जोड़ने के रूप में विफल रहता है:

all:
        diff <(echo test) <(echo test)

त्रुटि (संकेत: / बिन / श अंक / बिन / बाश इस प्रणाली पर):

/bin/sh: -c: line 0: syntax error near unexpected token `('
/bin/sh: -c: line 0: `diff <(echo test) <(echo test)'

इसका क्या मतलब है, और अस्थायी फ़ाइलों का उपयोग किए बिना दो आउटपुट को अलग करने का एक तरीका है?

जवाबों:


20

/bin/shbashआपके सिस्टम पर हो सकता है, लेकिन जब इसे लागू किया जाता है sh, bashतो POSIX मोड में चल रहा होगा (जैसे कि POSIXLY_CORRECTपरिभाषित किया गया था, या इसके साथ शुरू किया गया था --posix)।

इस मोड में, प्रक्रिया प्रतिस्थापन मौजूद नहीं हैं।

समाधान:

all:
    command1 >file1
    command2 >file2
    diff file1 file2
    rm -f file1 file2

वैकल्पिक:

all:
    bash -c "diff <(command1) <(command2)"

या बस Makefile चर SHELLको परिभाषित करें /bin/bash:

SHELL=/bin/bash

यदि आप पोर्टेबिलिटी चाहते हैं, तो पहले समाधान के साथ जाएं। यदि आप पर निर्भरता के साथ ठीक हैं bash, तो दूसरा चुनें। यदि आपको गैर-जीएनयू makeकार्यान्वयन के बारे में परवाह करने की आवश्यकता नहीं है , तो तीसरे का उपयोग करें।


सेटिंग के बारे में SHELL: पोसिक्स मानक का कहना है कि मेकफाइल्स में निष्पादन योग्यताओं को system()C लाइब्रेरी फ़ंक्शन द्वारा लागू किया जाना चाहिए make। यह फ़ंक्शन SHELLपर्यावरण चर का उपयोग करने की गारंटी नहीं है (वास्तव में, ऐसा करने से मानक द्वारा हतोत्साहित किया जाता है)। मानक यह कहने के लिए कुछ लंबाई में भी जाता है कि Makefile चर सेट करने SHELLसे पर्यावरण चर प्रभावित नहीं होना चाहिए SHELLmakeहालांकि, मुझे पता है कि ज्यादातर कार्यान्वयन में , मेकफाइल वेरिएबल SHELLका उपयोग कमांड्स को निष्पादित करने के लिए किया जाएगा।

उपयोगिता के लिए तर्कmake में सुझाव का उपयोग करना है bash -c:

MAKESHELLअन्य makeकार्यान्वयनों द्वारा प्रदान की गई ऐतिहासिक विशेषता और संबंधित सुविधाओं को छोड़ दिया गया था। कुछ कार्यान्वयन में इसका उपयोग उपयोगकर्ता को makeकमांड चलाने के लिए उपयोग किए जाने वाले शेल को ओवरराइड करने के लिए किया जाता है । यह भ्रामक था; एक पोर्टेबल के लिए make, शेल को मेफाइल लेखक द्वारा चुना जाना चाहिए। इसके अलावा, एक मेकफाइल लेखक को वैकल्पिक शेल का उपयोग करने की आवश्यकता नहीं होती है और फिर भी मेकफाइल पोर्टेबल पर विचार कर सकता है। हालांकि वैकल्पिक शेल को निर्दिष्ट करने के लिए एक तंत्र को मानकीकृत करना संभव होगा, मौजूदा कार्यान्वयन ऐसे तंत्र पर सहमत नहीं होते हैं, और मेकफाइल लेखक पहले से ही लक्ष्य के लिए नियम में शेल नाम निर्दिष्ट करके एक वैकल्पिक शेल आमंत्रित कर सकते हैं; उदाहरण के लिए:

python -c "foo"


क्या bashअस्थायी फ़ाइलों का उपयोग किए बिना अंतर समस्या के लिए मेकफाइल या किसी अन्य समाधान में आह्वान करने का कोई तरीका है ?
जोहान्स

बस दो अस्थायी फ़ाइलों का उपयोग करें, यह कमोबेश प्रक्रिया प्रतिस्थापन विधि है जो वैसे भी हुड के तहत करेगा।
Kusalananda

3
तुम भी सेट कर सकते हैं SHELLकरने के लिए /bin/bashMakefile में।
स्टीफन किट

1
@ जोहान्स कुसलानंद ने अपने जवाब में जानकारी को जोड़ा, जो बहुत अच्छा है क्योंकि यह कई विकल्प और परिस्थितियों को प्रस्तुत करता है जिसमें उनका उपयोग किया जा सकता है। मैं आपको इस उत्तर को स्वीकार करना चाहूंगा ... (लेकिन मैं भावना की सराहना करता हूं!)
स्टीफन किट

2
SHELL चर का उपयोग करने वाली जानकारी POSIX अनुरूप नहीं है, बहुत मददगार थी। शायद यह अभी भी उपयोग करना बेहतर है bash -c
जोहान्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.