2010-06-22 4 views
5

मेरे पास एक पर्ल स्क्रिप्ट है, script.pl जो, जब चलती है, एक कांटा करता है, पैरेंट प्रक्रिया एक फ़ाइल में अपनी पिड आउटपुट करती है तो बच्चे की प्रक्रिया के दौरान बाहर निकलती है स्टट करने के लिए कुछ आउटपुट करता है और फिर थोड़ी देर लूप में जाता है।perl कांटा दूरस्थ रूप से चलाते समय ठीक से काम नहीं करता है (एसएसएच के माध्यम से)

$pid = fork(); 

if (! defined $pid) 
{ 
    die "Failed to fork."; 
} 
#Parent process 
elsif($pid) 
{ 
    if(!open (PID, ">>running_PIDs")) 
    { 
     warn "Error opening file to append PID"; 
    } 
    print PID "$pid \n"; 
    close PID; 
} 
#child process 
else 
{ 
    print "Output started"; 

    while($loopControl)  
    { 
      #Do some stuff 
    } 
} 

यह ठीक काम करता है जब मैं इसे स्थानीय रूप से कहता हूं यानी: perl script.pl।

स्क्रिप्ट कुछ चीजों को प्रिंट करता है फिर शेल पर नियंत्रण वापस लौटाता है। (जबकि बाल प्रक्रिया पृष्ठभूमि में अपने लूप में बंद हो जाती है)।

हालांकि, जब मैं ssh नियंत्रण के माध्यम से इस फोन वापस कभी नहीं खोल में लौट आता है (और न ही "आउटपुट शुरू कर दिया" रेखा कभी मुद्रित है

अर्थात्:। $ ssh [email protected] 'पर्ल स्क्रिप्ट। pl '

हालांकि, दिलचस्प बात यह है, बच्चे प्रक्रिया को चलाने (मैं इसे जब मैं ps टाइप देख सकते हैं) है

किसी को क्या

संपादित हो रहा व्याख्या कर सकते हैं:।?

मैंने इसे डीबग के तहत चलाया और इसे मिला:

### फोर्क किया गया, लेकिन यह नहीं पता कि एक नया टीटीई कैसे बनाया जाए।

चूंकि दो डिबगर्स एक ही टीटीवी के लिए लड़ते हैं, इनपुट गंभीर रूप से उलझा हुआ है।

मुझे पता है कि आउटपुट को xterms और ओएस/2 कंसोल में केवल एक अलग विंडो में कैसे स्विच करें। मैन्युअल स्विच के लिए, $ DB :: fork_TTY में बनाए गए TTY का नाम दें, या इसे वापस करने वाले फ़ंक्शन डीबी :: get_fork_TTY() को परिभाषित करें।

यूनिक्स सिस्टम पर एक tty लिखकर दिया खिड़की के लिए एक TTY के नाम प्राप्त कर सकते हैं, और नींद से TTY से खोल डिस्कनेक्ट 1000000.

+1

अगर किसी के पास 'स्क्रीन' के अलावा इस समस्या का समाधान है (जो कि मैं हमेशा उपलब्ध नहीं हूं), तो मुझे इसे देखना अच्छा लगेगा। – mob

उत्तर

8

के साथ बाद में पुनः अनुलग्न , आपको stdin, stdout, & stderr को बंद या अन्यथा बंद करना होगा। अन्यथा एसएसएच पृष्ठभूमि प्रक्रिया को बाहर निकलने के लिए इंतजार करेगा। FAQ

इसे नियंत्रित टर्मिनल से अलग करना या अलग करना कहा जाता है और केवल एसएसएच के लिए पृष्ठभूमि नौकरियां लिखते समय सामान्य सामान्य अभ्यास होता है।

#close std fds inherited from parent 
close STDIN; 
close STDOUT; 
close STDERR; 

सही अपने print "Output started"; के बाद:

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

+0

बहुत बढ़िया काम किया! एफएक्यू लिंक –

+0

+1 अपनी पोस्ट पढ़ने से पहले डिबगिंग के लिए बर्बाद घंटे। धन्यवाद, यह काम करता है! – bitmask

+0

के लिए – Shamanu4

4

ssh [email protected] 'nohup perl script.pl'

आप में सक्षम नहीं हैं बाहर निकलने के लिए क्योंकि अभी भी एक प्रक्रिया संलग्न है। आपको nohup की आवश्यकता है।

+0

कोई प्रभाव नहीं लग रहा है। = [ –

+0

+1 सही निदान। -1 गलत पर्चे। – mob

2

क्या हो रहा है कि एसएसएच 'perl script.pl' को सीधे कमांड के रूप में निष्पादित कर रहा है। आप 'स्क्रीन' उपलब्ध है, तो आप कर सकता है:

$ ssh [email protected] 'screen -d -m perl script.pl' 

यह एक अलग स्क्रीन पर चल रहा है, और जब भी आप गैर-सहभागी ssh कमांड के माध्यम से पृष्ठभूमि नौकरियों लांच स्क्रीन -r

+0

यह काम करता है, नियंत्रण वापस कर दिया जाता है। एसएसएच के माध्यम से इसे दूरस्थ रूप से चलाने के बारे में क्या इसे स्थानीय रूप से चलाने से अलग है? हाउ कब आती है जब स्थानीय होती है तो इसमें कोई समस्या नहीं होती है? –

+1

@Razor, दूरस्थ रूप से चलते समय, * कोई * खोल नहीं है - दूसरी तरफ एसएसएच डिमन चलता है और स्क्रिप्ट पर खुद को जोड़ता है। आप शायद 'bash -c "perl script.pl" ssh कमांड – friedo

+0

चलाकर जो भी चाहते हैं उसे प्राप्त कर सकते हैं, हालांकि, मूल प्रक्रिया समाप्त होती है, इसलिए संलग्न डिमन भी चलना बंद नहीं करना चाहिए? –

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