2011-12-16 5 views
7

मैं कैसे निर्धारित करूं कि मेरी पर्ल स्क्रिप्ट को किस स्क्रिप्ट, प्रोग्राम या शैल को निष्पादित किया गया?मैं कैसे पता लगा सकता हूं कि मेरी पर्ल स्क्रिप्ट को किस स्क्रिप्ट, प्रोग्राम या शैल को निष्पादित किया गया है?

उदाहरण: मैं शैल से निष्पादित (प्रत्येक प्रकार के खोल के लिए अनुकूलित) से निष्पादित होने पर मानव पठनीय आउटपुट प्राप्त करना चाहूंगा, एक अलग प्रकार के आउटपुट को अगर किसी अन्य पर्ल स्क्रिप्ट से स्क्रिप्ट के रूप में बुलाया जाता है, और मशीन से पठनीय प्रारूप से निष्पादित किया जा सकता है एक सतत एकीकरण सर्वर जैसे एक कार्यक्रम।

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

संपादित करें: इनमें से कई उत्तर लिनक्स विशिष्ट होते हैं। असुविधाजनक रूप से, पावरहेल विंडोज के लिए है। getppid, $ENV{SHELL} चर, और ps पर खोलने से इस मामले में मदद नहीं मिलेगी। इस स्क्रिप्ट को क्रॉस-प्लेटफ़ॉर्म चलाने की आवश्यकता है।

+0

मुझे यकीन नहीं है कि मैं समझता हूं - क्या आप उस मामले में मूल प्रक्रिया को नहीं देख रहे हैं? – x0n

+0

आप यह देखने के लिए परीक्षण कर सकते हैं कि क्या STDOUT एक टर्मिनल ('-t') है और यदि ऐसा है, तो मान लें कि आपको निरंतर एकीकरण डिमन के बजाय एक इंटरैक्टिव खोल से बुलाया गया है। हालांकि यह आम तकनीक उत्पादन प्रति-विशिष्ट-माता-पिता को अनुकूलित करने के लिए बात नहीं करती है (लेकिन मुझे लगता है कि यह एक गलत जगह है, वैसे भी)। – pilcrow

+0

उल्लेख करने के लिए भूल गए, आम तौर पर यह एक पर्यावरण परिवर्तनीय दिखता है कि खोल या उपयोगकर्ता यह इंगित करता है कि कौन सा खोल चल रहा है; पावरहेल के साथ, ऐसा कोई पर्यावरण चर नहीं है। –

उत्तर

1

आपके पर्यावरण के आधार पर, आप इसे पर्यावरण चर से चुनने में सक्षम हो सकते हैं। निम्नलिखित कोड पर विचार करें:

/usr/bin/perl -MData::Dumper -e 'print Dumper(\%ENV);' | grep sh 

मेरे Ubuntu प्रणाली पर, यह मुझे हो जाता है:

'SHELL' => '/bin/bash', 

तो मुझे लगता है कि जो कहता है कि मैं एक bash खोल से पर्ल चल रहा हूँ। यदि आप कुछ और उपयोग करते हैं, तो SHELL चर आपको एक संकेत दे सकता है।

लेकिन मान लें कि आप जानते हैं कि आप बाश में हैं, लेकिन पर्ल एक सबहेल से चलाया जाता है। फिर प्रयास करें:

/bin/sh -c "/usr/bin/perl -MData::Dumper -e 'print Dumper(\%ENV);'" | grep sh 

आप पाएंगे:

 '_' => '/bin/sh', 
     'SHELL' => '/bin/bash', 

तो खोल अभी भी पार्टी है, लेकिन पार्टी है एक चर $_ जो भी खोल या स्क्रिप्ट के पूर्ण फ़ाइल नाम दिखाने निष्पादित किया जा रहा है, जो हो सकता है एक मूल्यवान संकेत भी देते हैं। इसी तरह, अन्य वातावरणों के लिए संभवतया पेर्ल %ENV हैश में छोड़े गए संकेत होंगे जो आपको मूल्यवान संकेत दे सकते हैं।

+0

आह, आखिरकार समझ में आया कि मैं क्यों नीचे आ गया। अब तक पावरहेल टैग नहीं देखा। मेरी गलती। –

+0

मुझे नहीं था जो आपको नीचे गिरा दिया था, लेकिन मुझे एक पर्यावरण चर के लिए प्यार करना होगा ताकि मुझे बता सकें कि शक्तियां चल रही हैं। दुर्भाग्यवश, पावरहेल में ऐसा चर नहीं है। स्क्रिप्ट अन्य शैल प्रकारों के लिए आउटपुट का निर्धारण करने के लिए पर्यावरण का उपयोग करती है। –

+0

यहां देख रहे हैं http://vlaurie.com/computers2/Articles/environment-variables-windows-vista-7.htm यह डिफ़ॉल्ट रूप से cmd.exe को COMSPEC बिंदुओं की तरह दिखता है; शायद PowerShell के तहत चलाए जाने पर PowerShell निष्पादन योग्य को इंगित करता है? यदि ऐसा है, तो आप सिग्विन और इसी तरह के वातावरण से रनटाइम पर्यावरण को समझने में सक्षम होना चाहिए ... –

5

आप getppid() का उपयोग करते हैं। child.pl में इस स्निपेट लें:

my $ppid = getppid(); 
system("ps --no-headers $ppid"); 

आप कमांड लाइन से चलाते हैं, systembash या इसी तरह के (अन्य बातों के अलावा) दिखाई देगा। इसे किसी अन्य स्क्रिप्ट में system("perl child.pl"); के साथ निष्पादित करें, उदा। parent.pl, और आप देखेंगे कि perl parent.pl इसे निष्पादित किया गया।

बस तर्क के साथ प्रक्रिया के नाम पर कब्जा करने के लिए (धन्यवाद सही ps वाक्य रचना के लिए Ikegami के लिए):

my $ppid = getppid(); 
my $ps = `ps --no-headers -o cmd $ppid`; 
chomp $ps; 

संपादित करें: इस दृष्टिकोण के लिए एक वैकल्पिक, करने के लिए मुलायम लिंक बनाने के लिए हो सकता है आपके स्क्रिप्ट, विभिन्न संदर्भों को अपनी स्क्रिप्ट तक पहुंचने के लिए विभिन्न लिंक का उपयोग करें और इसके आसपास तर्क बनाने के लिए $0 का निरीक्षण करें।

+2

थोड़ा और भरोसेमंद: 'chomp (मेरा $ parent_name = \' ps --no-headers -o cmd $ ppid \ ');' – ikegami

+0

@ikegami: धन्यवाद। :) मुझे नहीं पता था कि प्रारूप को निर्दिष्ट करने के बारे में कैसे जाना है। – flesk

+0

दुर्भाग्यवश, विंडोज़ पर पर्ल 'getppid()' का समर्थन नहीं करता है और न ही 'ps' को संभावना है। :( –

3

मैं आपके लक्ष्य को पूरा करने के लिए एक अलग दृष्टिकोण का सुझाव दूंगा।संदर्भ में अनुमान लगाने के बजाय, इसे और अधिक स्पष्ट बनाएं। प्रत्येक उपयोग का मामला पूरी तरह से अलग है, इसलिए तीन अलग-अलग इंटरफेस हैं।

  1. एक फ़ंक्शन जिसे एक पर्ल प्रोग्राम के अंदर बुलाया जा सकता है। यह एक पर्ल डेटा संरचना वापस करने की संभावना होगी। यह स्क्रिप्ट आउटपुट पार्सिंग से कहीं अधिक आसान, तेज़ और अधिक विश्वसनीय है। यह स्क्रिप्ट के आधार के रूप में भी काम करेगा।

  2. एक स्क्रिप्ट जो वर्तमान खोल के लिए आउटपुट करती है। शेल चल रहा है यह जानने के लिए यह $ENV{SHELL} पर देख सकता है। बोनस अंक के लिए, स्पष्ट रूप से ओवरराइड करने के लिए एक स्विच प्रदान करें।

  3. एक स्क्रिप्ट जिसे गैर-पर्ल प्रोग्राम के अंदर बुलाया जा सकता है, जैसे आपका सतत एकीकरण सर्वर, और समस्या मशीन पठनीय आउटपुट। एक्सएमएल और/या जेएसओएन या जो भी हो।

2 और 3 बस पतली रैपर डेटा की 1.

प्रत्येक का विशिष्ट जरूरत के अनुरूप फिट है बाहर आ रहा फ़ॉर्मेट करने के लिए किया जाएगा। प्रत्येक ह्यूरिस्टिक्स के बिना काम करेगा। प्रत्येक संदर्भ का अनुमान लगाने और उपयोगकर्ता क्या चाहता है, उससे कहीं अधिक सरल होगा।

यदि आप 2 और 3 को अलग नहीं कर सकते हैं, तो निरंतर एकीकरण सर्वर एक पर्यावरण चर सेट करता है और इसके लिए देखता है।

+0

सामान्य मामले में, सहमत हुए। जैसा कि मैंने उल्लेख किया है, उपरोक्त इस तकनीक के संभावित अनुप्रयोगों के उदाहरण थे। इस मामले में, स्क्रिप्ट एक शेल स्क्रिप्ट को उत्सर्जित करती है, और अन्य टूल्स स्क्रिप्ट का आह्वान करने वाले शेल के लिए सही प्रकार की शेल स्क्रिप्ट को उत्सर्जित करने की अपेक्षा करते हैं। लगभग सभी अन्य गोले के लिए, पर्यावरण चर हैं जो इंगित करते हैं कि कौन सा खोल उपयोग करना है। पावरहेल ऐसा चर नहीं देता है। –

1

यह विंडोज़ XP पर PowerShell v2.0 के साथ है, इसलिए इसे नमक के अनाज के साथ लें।

एक cmd.exe खोल में, मैं मिलता है:

PSModulePath=C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\

जबकि PowerShell कंसोल विंडो में, मैं मिलता है:

PSModulePath=E:\Home\user\WindowsPowerShell\Modules;C:\WINDOWS\system32\WindowsP owerShell\v1.0\Modules\

जहां E:\Home\user जहाँ मेरे "मेरे दस्तावेज़" फ़ोल्डर है है। तो, एक हेरिस्टिक यह जांचने के लिए हो सकता है कि PSModulePath में उपयोगकर्ता निर्भर पथ है या नहीं।

इसके अलावा, एक कंसोल विंडो में, मैं मिलता है:

!::=::\

वातावरण में। PowerShell आईएसई से, मैं मिलता है:

!::=::\ 
!C:=C:\Documents and Settings\user
+0

+1 - आह, बकवास। मैंने आपका जवाब भी नहीं देखा। मैंने बस एक ही चीज़ का पता लगाया। वैसे, यह शक्तिशक्ति 1.0 नहीं है - v1 मॉड्यूल का समर्थन नहीं करता है। % Windir% के तहत पथ v1.0 v1.0 v शक्तियों के v1, v2 और v3 के लिए है। – x0n

1

आप ऊपर PowerShell 2.0 या (सबसे अधिक संभावना) द्वारा चलाए जा रहे हैं, तो आप वातावरण चर %psmodulepath% का परीक्षण करके एक माता पिता प्रक्रिया के रूप में खोल अनुमान लगा सकते हैं। डिफ़ॉल्ट रूप से, यह %windir%\system32\windowspowershell\v1.0\modules के तहत सिस्टम मॉड्यूल को इंगित करता है; यदि आप cmd.exe से चर की जांच करते हैं तो यह वही होगा जो आप देखेंगे।

हालांकि, जब PowerShell शुरू होता है, तो यह इस पर्यावरण चर के लिए उपयोगकर्ता का डिफ़ॉल्ट मॉड्यूल खोज पथ तैयार करता है जो इस तरह दिखता है: %userprofile%\documents\windowspowershell\modules। यह बाल प्रक्रियाओं द्वारा विरासत में मिला है। इसलिए, आपका तर्क परीक्षण करना होगा कि% psmodulepath%% userprofile% के साथ पावरहेल 2.0 या उच्चतम का पता लगाने के लिए शुरू होता है। यह PowerShell 1.0 में काम नहीं करेगा क्योंकि यह मॉड्यूल का समर्थन नहीं करता है।

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

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