2010-11-23 16 views
8

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

क्या स्क्रिप्ट का आह्वान करने के लिए बैश में कोई तरीका है?

+1

इसे देखने का दूसरा तरीका यह है कि, आप एक रैपर स्क्रिप्ट का उपयोग क्यों नहीं करते हैं जो आउटपुट को स्वयं पाइप करता है? तो, विस्मयकारी विंडो प्रबंधक स्क्रिप्ट- wrapper.sh कहते हैं, और इसमें पंक्ति "./script.sh >> awesome.log" – laher

+1

शैल स्क्रिप्ट के उपयोगकर्ता के रूप में, मैं इसे पसंद करता हूं जब स्क्रिप्ट बहुत चालाक होने की कोशिश नहीं करते हैं । अगर मैं एक फाइल में आउटपुट चाहता हूं, तो मैं इसे फाइल में रखने में पूरी तरह से सक्षम हूं। फ़ाइल में आउटपुट भेजने के लिए स्क्रिप्ट को एक रैपर या ध्वज प्रदान करना (जैसे '-o फ़ाइल नाम') आदर्श - आसान, लेकिन स्पष्ट होगा। –

+0

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

उत्तर

16

इस प्रयास करें:: उस मामले में आप एक अधिक बहुमुखी शर्त यह है कि यह भी मानक इनपुट की जाँच करेगा (फ़ाइल वर्णनकर्ता 0) चाहते हो सकता है

ps -o stat= -p $PPID 

परिणाम "एस" शामिल हैं (लोअरकेस) यह या तो कमांड लाइन से चलाया गया था या एक स्क्रिप्ट के भीतर से पृष्ठभूमि में था। उन दोनों को अलग करने के लिए:

ps -o stat= -p $$ 

में "+" होगा यदि यह पृष्ठभूमि नहीं था।

यहाँ एक मेज है:

Run   $$ $PPID 
CL   S+ Ss 
CL&   S  Ss+ 
Script  S+ S+ 
Script&  S  S 
Script(&) S  Ss 
Script&(&) S  NULL 

कहाँ (&) का अर्थ है बच्चे स्क्रिप्ट backgrounded किया गया था और & माता पिता स्क्रिप्ट (जो "स्क्रिप्ट" क्या संदर्भित करता है) कि भाग गया यह backgrounded था मतलब है। सीएल का मतलब कमांड लाइन है। नल का मतलब है कि पीएस आउटपुट एक शून्य और $PPID "1" है।

man ps से:

s is a session leader 
    + is in the foreground process group 

यह है कि इस सवाल का जवाब जीएनयू ps पर आधारित है ध्यान दिया जाना चाहिए, लेकिन बीएसडी (ओएस एक्स सहित) के लिए आदमी पृष्ठों इसी तरह की सुविधा से संकेत मिलता है। और जीएनयू ps एक संकर है जिसमें बीएसडी कार्यक्षमता शामिल है, दूसरों के बीच।

+2

"स्क्रिप्ट" का अर्थ है स्क्रिप्ट के बजाय, मूल प्रश्न, जो प्रश्न का विषय है। –

+0

बहुत अच्छा समाधान। –

-1

आप की तरह

PARENT=`ps --no-heading -o %c -p $PPID` 
    echo $PARENT 

यह $ PPID

कुछ इस्तेमाल कर सकते हैं माता पिता की प्रक्रिया नाम के PARENT चर सेट होगा, और फिर स्क्रीन पर इसे प्रिंट।

फिर आप कुछ डाल सकता है अगर $ PARENT के मूल्य पर आधारित बयान

HTH

+0

मैंने इसका परीक्षण किया और इससे कोई फर्क नहीं पड़ता कि मैं इसे सीधे या किसी अन्य * बैश * स्क्रिप्ट से चलाता हूं, यह प्रिंट करता है "बैश" – ndemou

+0

@ndemou उबंटू 16.04, कर्नेल 4.4.0-53 के तहत पुष्टि करें, और पांच साल बाद भी यह "बैश" प्रिंट करता है। – WinEunuuchs2Unix

7

मुझे विश्वास है कि आप वास्तव में क्या जानना चाहते हैं कि क्या stdout एक टर्मिनल है या नहीं है। यदि ऐसा है तो आप (लगभग) सुरक्षित रूप से मान सकते हैं कि यह एक इंटरैक्टिव सत्र है। निम्नलिखित स्निपेट का प्रयास करें:

if [[ -t 1 ]]; then 
     echo "Terminal" 
else 
     echo "Not-a-terminal" 
fi 

[[ -t 1 ]] आदेश ऊपर क्या जाँच करता है, तो फ़ाइल वर्णनकर्ता 1 (अर्थात stdout) एक टर्मिनल है या नहीं है।

संपादित करें:

कृपया ध्यान दें कि यह एक गैर टर्मिनल stdout से संकेत मिलता है अगर आप पाइप कुछ अन्य कार्यक्रम के लिए उत्पादन।

[[ -t 0 || -t 1 ]] 
+0

लेकिन आप यह जानना चाहेंगे कि यह एक कमांड लाइन से चलाया गया है, भले ही stdout टर्मिनल पर नहीं है (जैसे कि यह पाइप में है)। –

+0

@ डेनिस: मुझे नहीं लगता कि इसके लिए एक सार्वभौमिक या जादुई समाधान है। पीपीआईडी ​​विधि प्रभावी है, लेकिन अगर स्क्रिप्ट को किसी अन्य स्क्रिप्ट के माध्यम से बुलाया जाता है तो यह भी असफल हो जाता है। – thkala

+0

क्या आप तीसरे स्तर के बारे में बात कर रहे हैं? स्क्रिप्ट कॉलिंग स्क्रिप्ट कॉलिंग स्क्रिप्ट? आप अभी भी मेरे उत्तर में तकनीक का उपयोग यह निर्धारित करने के लिए कर सकते हैं कि ब्याज की स्क्रिप्ट कमांड लाइन से चलती है या नहीं। –

1

यह एक ऐसा कार्य है जिसे मैंने इस विषय के बारे में एक और पोस्ट से अनुकूलित किया है। यह $shells चर में सूचीबद्ध वस्तुओं के विरुद्ध शीर्ष पर सभी मूल प्रक्रियाओं से मेल खाता है। जब यह किया जाता है $iscli या तो 0 या 1 पर सेट किया गया है। यदि यह 0 पर सेट है, तो आप जानते हैं कि यह एक खोल से चलाया गया था या आप इस उद्देश्य के लिए पर्याप्त गोले पर विचार करते हैं। यदि यह 1 पर सेट है, तो आप जानते हैं कि एक प्रोग्राम शामिल था जो अनुमोदित नहीं है। मैं इसे उन स्क्रिप्ट के लिए उपयोग करता हूं जिन्हें मैं एक खोल में और PHP के माध्यम से चलाने के लिए चाहता हूं, जब मैं प्रत्येक को अलग-अलग आउटपुट प्रदान करना चाहता हूं।

मूल्य रखने के लिए आपको $iscli की आवश्यकता होने से पहले आपको किसी भी पैरामीटर के बिना प्रारंभ में फ़ंक्शन को कॉल करने की आवश्यकता होगी।

function top_level_parent_pid { 

    scriptname="${0##*/}" 
    shells="^bash|^init|^screen|^sh|^ssh|^su|${scriptname}" 

    pid=${1:-$$} 
    pidname="`ps --no-heading -o %c -p ${pid}`" 
    stat=($(</proc/${pid}/stat)) 
    ppid=${stat[3]} 
    ppidname="`ps --no-heading -o %c -p ${ppid}`" 
    isclitest="`echo "${ppidname}" | grep -iv -E "${shells}"`" 

    until [ "${ppid}" -eq "1" ] || [ "${iscli}" = "1" ]; do 

      if [[ -n "${isclitest}" ]]; then 

        iscli="1" 

       else 

        iscli="0" 


        top_level_parent_pid ${ppid} 
      fi 
    done 
} 
संबंधित मुद्दे