अनाथ प्रक्रिया समूहों में इंटरैक्टिव गोले क्या करना चाहिए?


10

( Https://stackoverflow.com/questions/13718394/what-should-interactive-shells-do-in-orphaned-process-groups में सुझाव के अनुसार यूनिक्स में पुनः पोस्टिंग )

संक्षिप्त प्रश्न यह है कि यदि अनाथ प्रक्रिया समूह में ऐसा कोई शेल है तो उसे क्या करना चाहिए? लेकिन मैं लंबे प्रश्न को पढ़ने की सलाह देता हूं क्योंकि यह मनोरंजक है।

अपने पसंदीदा शेल (जब तक कि आप उन अजीब योगों में से एक नहीं हैं) का उपयोग करके अपने लैपटॉप को पोर्टेबल स्पेस हीटर में बदलने का एक मजेदार और रोमांचक तरीका है:

#include <unistd.h>   
int main(void) {
    if (fork() == 0) {
        execl("/bin/bash", "/bin/bash", NULL);
    }
    return 0;
}

यह सीपीयू को 100% कम करने के लिए बैश का कारण बनता है। zsh और मछली भी ऐसा ही करते हैं, जबकि ksh और tcsh नौकरी नियंत्रण के बारे में कुछ गुनगुनाते हैं और फिर उलटना करते हैं, जो थोड़ा बेहतर है, लेकिन ज्यादा नहीं। ओह, और यह एक प्लेटफ़ॉर्म अज्ञेयवादी अपराधी है: ओएस एक्स और लिनक्स दोनों प्रभावित हैं।

मेरी (संभावित रूप से गलत) व्याख्या इस प्रकार है: बच्चा खोल पता लगाता है कि यह अग्रभूमि में नहीं है tcgetpgrp(0) != getpgrp():। इसलिए यह खुद को रोकने की कोशिश करता है killpg(getpgrp(), SIGTTIN):। लेकिन इसका प्रोसेस ग्रुप अनाथ है, क्योंकि इसके पैरेंट (C प्रोग्राम) लीडर थे और मर गए, और SIGTTINअनाथ प्रोसेस ग्रुप में भेज दिया जाता है। इसलिए, बच्चे के खोल को रोका नहीं गया है, लेकिन यह अभी भी पृष्ठभूमि में है, इसलिए यह यह सब फिर से करता है, तुरंत। धोये और दोहराएं।

मेरा सवाल यह है कि कमांड लाइन शेल इस परिदृश्य का पता कैसे लगा सकता है, और इसके लिए क्या करना सही है? मेरे पास दो समाधान हैं, जिनमें से कोई भी आदर्श नहीं है:

  1. उस प्रक्रिया को इंगित करने का प्रयास करें जिसका पीआईडी ​​हमारे समूह आईडी से मेल खाता है। अगर वह विफल रहता है ESRCH, तो इसका मतलब है कि हम शायद अनाथ हैं।
  2. एक बाइट से एक गैर-अवरुद्ध पढ़ने की कोशिश करें /dev/tty। अगर वह विफल रहता है EIO, तो इसका मतलब है कि हम शायद अनाथ हैं।

(इस पर नज़र रखने वाला हमारा मुद्दा https://github.com/fish-shell/fish-shell/issues/422 है )

आपके विचारों के लिए धन्यवाद!

जवाबों:


4

मैं आपके विश्लेषण से सहमत हूं और मैं मानता हूं कि यह लगता है कि आपको पता लगाना है कि आपका प्रक्रिया समूह अनाथ है या नहीं।

tcsetattrEIOयदि प्रक्रिया समूह अनाथ है (और हम SIGTT OU को अवरुद्ध / अनदेखा नहीं कर रहे हैं, तो लौटने का मतलब है । यह readटर्मिनल की तुलना में कम घुसपैठ का तरीका हो सकता है ।

ध्यान दें कि आप इसे फिर से बना सकते हैं:

(bash<&1 &)

बैकग्राउंड में कमांड चलाने पर आपको रीडायरेक्शन की आवश्यकता होती है अन्यथा स्टड को रीडायरेक्ट किया जाता है।

(bash<&1 & sleep 2)

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

ksh93समाधान इतना बुरा नहीं है: केवल देने से पहले उस लूप के माध्यम से 20 गुना (अनंत के बजाय) तक जाएं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.