2010-11-23 9 views
5

मेरे पास एक मेकफ़ाइल है जो कमांड लेती है जो थोड़ी देर ले सकती है। मैं उन आदेशों को चतुर होना चाहूंगा यदि निर्माण एक इंटरैक्टिव खोल से शुरू किया गया हो लेकिन शांत नहीं है (विशेष रूप से, क्रॉन द्वारा)। (छद्म कोड) की रेखाओं के साथ कुछ:मैं कैसे बता सकता हूं कि एक इंटरैक्टिव खोल से मेकफ़ाइल चलाया जा रहा है या नहीं?

foo_opts = -a -b -c 
if (make was invoked from an interactive shell): 
    foo_opts += --verbose 

all: bar baz 
    foo $(foo_opts) 

यह जीएनयू बनाना है। यदि मैं जो कुछ भी कर रहा हूं उसके विनिर्देश, मैं प्रश्न संपादित कर सकता हूं।

उत्तर

5

यह सख्ती का निर्धारण नहीं है कि यह एक इंटरैक्टिव खोल या नहीं से शुरू हो जाती है, लेकिन एक क्रॉन जॉब जिसमें उत्पादन एक फ़ाइल पर भेज दिया जाएगा के लिए, इस सवाल का जवाब How to detect if my shell script is running through a pipe? के लिए के रूप में ही होगा:

if [ -t 0 ] 
then 
    # input is from a terminal 
fi 

संपादित करें: इस का उपयोग करने के (जीएनयू में बनाने के लिए, वह यह है कि) एक Makefile में एक चर सेट करने के लिए:

INTERACTIVE:=$(shell [ -t 0 ] && echo 1) 

ifdef INTERACTIVE 
# is a terminal 
else 
# cron job 
endif 
+0

(ए) मेकफ़ाइल में आप उस परीक्षण को कैसे बनाते हैं? (बी) मैं अक्सर एक इंटरैक्टिव खोल से बना देता हूं जिसमें दोनों स्टडआउट और स्टडर को पाइप पर रीडायरेक्ट किया जाता है (जो आउटपुट की प्रतिलिपि रिकॉर्ड-रखरखाव के लिए फ़ाइल में भेजता है और इसे मेरे टर्मिनल पर भी भेजता है), तो परीक्षण होगा मेरे लिए असफल –

+0

@ जोनाथन लेफ्लर: स्टडीन काम का उपयोग करेंगे? – PleaseStand

+0

अधिकतर ... यह अक्सर एक विश्वसनीय टर्मिनल से जुड़ा हुआ है या नहीं, यह अक्सर सबसे विश्वसनीय जांच है; कुछ लोग '' बनाओ

4

http://www.faqs.org/faqs/unix-faq/faq/part5/section-5.html

5,5) मैं कैसे बता सकता है कि अगर मैं एक इंटरैक्टिव खोल चल रहा हूँ?

In the C shell category, look for the variable $prompt. 

    In the Bourne shell category, you can look for the variable $PS1, 
    however, it is better to check the variable $-. If $- contains 
    an 'i', the shell is interactive. Test like so: 

     case $- in 
     *i*) # do things for interactive shell 
       ;; 
     *)  # do things for non-interactive shell 
       ;; 
     esac 
+1

अपने परेड पर बारिश के लिए खेद है, लेकिन यह आपको बताता है कि आप जो खोल चल रहे हैं वह अंतःक्रियात्मक रूप से चलाया गया था, लेकिन मेकफ़ाइल के अंदर, आपके द्वारा चलाए जाने वाले किसी भी खोल का दावा होगा कि यह गैर-संवादात्मक रूप से चलाया जा रहा है, भले ही 'मेक' खुद एक इंटरैक्टिव खोल से भागते हैं। सबूत: 'मेकफ़ाइल' में ''all:; echo" शैल: $$ - "'' और 'मेक' चलाएं और इसमें आउटपुट में 'i' शामिल नहीं होगा। (मेरे मैक पर, मुझे 'इंटरबैक्टिव शैल' से 'एचबीबी' की तुलना में 'मेक' से 'एचबीसी' मिला। –

+0

हम्म .. हो सकता है कि ओपी शेल में इंटरैक्टिव की जांच कर सके जो आमंत्रित करता है और एक पर्यावरण चर सेट करता है जो हो सकता है मेकफ़ाइल में कब्जा कर लिया। – Naveen

+0

अधिकतर पर्यावरण परिवर्तनीय प्रकार का काम करता है, लेकिन यह बहुत संतोषजनक नहीं है। –

4

मुझे नहीं लगता कि आप आसानी से पता लगा सकते हैं। मैं क्रॉन नौकरी से वर्बोज़ आउटपुट को कुचलने के द्वारा, वैकल्पिक रणनीति को अपनाने का सुझाव देता हूं। मैं इस तरह एक makefile का उपयोग कर ऐसा करने के लिए दिखेगा:

VERBOSE = --verbose 

foo_opts = -a -b -c ${VERBOSE} 

all: bar baz 
    foo $(foo_opts) 

फिर क्रॉन जॉब में,, निर्दिष्ट करें:

make VERBOSE= 

वर्बोज़ का यह आदेश-पंक्ति विनिर्देश makefile में एक ओवरराइड करता है (और मेकफ़ाइल द्वारा बदला नहीं जा सकता है)। इस तरह, विशेष कार्य (क्रॉन जॉब) जिसे आप एक बार स्थापित करते हैं और कई बार उपयोग करते हैं, वर्बोज आउटपुट के बिना किया जाएगा; इमारत का सामान्य कार्य शब्दशः किया जाएगा (जब तक आप कमांड लाइन पर वर्बोज़-नेस को ओवरराइड करने का विकल्प नहीं चुनते)।

इस तकनीक का एक मामूली लाभ यह है कि यह make के किसी भी प्रकार के साथ काम करेगा; यह किसी भी जीएनयू मेक सुविधा पर निर्भर नहीं है।

0

मैं सच में यकीन है कि क्या "हूँ इंटरैक्टिव" का अर्थ है नहीं कर रहा हूँ। क्या आपका मतलब है कि आपके पास वैध /dev/tty है? यदि ऐसा है, तो आप इसे देख सकते हैं। हम में से अधिकांश stdin पर isatty जांचते हैं, हालांकि, क्योंकि हम उन प्रश्नों का उत्तर देते हैं जिन्हें हम जानना चाहते हैं: क्या कोई है जो कुछ टाइप करने के लिए है।

+0

समस्या यह है कि आप बच्चे को यह जानना चाहते हैं कि माता-पिता इंटरैक्टिव है या नहीं और आप ऐसा नहीं कर सकते क्योंकि यह बच्चे में चलने पर बच्चे की स्थिति लौटाता है। –

0

बस एक नोट: आप the related discussion भी देख सकते हैं कि मुझे मेकफ़ाइल के अंदर से STDOUT के पुनर्निर्देशन का पता लगाने के बारे में था।

मेरा मानना ​​है कि यह इस सवाल के पाठकों के लिए उपयोगी होगा - कार्यकारी सारांश:

-include piped.mk 

all: piped.mk 
ifeq ($(PIPED),1) 
    @echo Output of make is piped because PIPED is ${PIPED} 
else 
    @echo Output of make is NOT piped because PIPED is ${PIPED} 
endif 
    @rm -f piped.mk 

piped.mk: 
    @[ -t 1 ] && PIPED=0 || PIPED=1 ; echo "PIPED=$${PIPED}" > piped.mk 

$ make 
Output of make is NOT piped because PIPED is 0 

$ make | more 
Output of make is piped because PIPED is 1 

मेरा उत्तर में मैं स्पष्टीकरण दें कि [-t 1] एक कार्रवाई में और एक चर काम में नहीं किया जा सकता है (के रूप में यहां दिए गए अनुशंसित उत्तर में), साथ ही जेनरेट किए गए मेकफ़ाइल (यानी piped.mk) के पुनर्मूल्यांकन के संबंध में विभिन्न नुकसान।

इस प्रश्न में इंटरैक्टिव शब्द STDIN का पुनर्निर्देशन प्रतीत होता है ...इस मामले में [ -t 1 ] को [ -t 0 ] के साथ उपरोक्त मेरे कोड में बदलना चाहिए जैसा कि है।

उम्मीद है कि इससे मदद मिलती है।

संबंधित मुद्दे

 संबंधित मुद्दे