क्या एक इंटरैक्टिव शेल गैर-इंटरैक्टिव या इसके विपरीत बन सकता है?
नोट: मैंने मूल प्रश्न पर बहुत सारे शोध किए हैं, "इंटरैक्टिव और गैर-इंटरैक्टिव के बीच अंतर क्या है?", और मेरे शोध के परिणामों ने मुझे यह सवाल पूछा।
इस प्रश्न का एक लंबा प्रस्तावना भाग है क्योंकि यह महत्वपूर्ण है कि हम इसका उत्तर देने के लिए किस प्रकार की परिभाषा "इंटरैक्टिव" के लिए उपयोग करते हैं। एक परिभाषा एक निश्चित सेट के लिए एक मनमाना लेबल हो सकती है; यह विभिन्न गुणों का विवरणात्मक हो सकता है; या यह आपको जानकारी दे सकता है जिसका उपयोग आप व्यवहार की भविष्यवाणी करने और उद्देश्य को समझने के लिए कर सकते हैं । इस अंतिम प्रकार को हम "एक्शन डेफिनिशन" या "डायनेमिक परिभाषा" कह सकते हैं और यह सबसे उपयोगी है।
में man 1p sh
, एक इंटरैक्टिव खोल के निम्नलिखित परिभाषा दी गई है:
If the -i option is present, or if there are no operands and the shell’s standard input and standard error are attached to a terminal, the shell is considered to be interactive.
"-I विकल्प" और "ऑपरेंड्स" शब्द के उपयोग के उल्लेख से, यह एक शेल के आह्वान का उल्लेख कर रहा है , न कि उन विशेषताओं का जो एक रनिंग शेल में जांच की जा सकती हैं।
बैश मैन पेज के वाक्यांशों में यह थोड़ा अलग है:
An interactive shell is one started without non-option arguments and without the -c option whose standard input and error are both connected to terminals (as determined by isatty(3)), or one started with the -i option. PS1 is set and $- includes i if bash is interactive, allowing a shell script or a startup file to test this state.
पहले वाक्य में परिभाषा फिर से केवल शेल की शुरुआत को संदर्भित करती है ।
दूसरा वाक्य (मेरे पढ़ने में) उन स्थितियों को परिभाषित करता है, जो कि यह सुनिश्चित करने के लिए समीपता के रूप में उपयोग की जाती हैं कि क्या शेल को उन विशेष तरीकों से शुरू किया गया था जिन्हें "इंटरैक्टिव" के रूप में परिभाषित किया गया है।
ध्यान दें कि मैं इस वाक्य की व्याख्या नहीं$-
करता हूं : "एक बैश शेल इंटरएक्टिव है अगर और केवल अगर 'आई' शामिल है।" $-
लगता है सिर्फ एक आसान संकेतक है, न कि इंटरैक्टिव की परिभाषा । यह मेरे प्रश्न के लिए महत्वपूर्ण रूप से प्रासंगिक है।
ये दोनों (POSIX sh
परिभाषा और बाश की) यांत्रिक परिभाषाएं हैं जो बताती हैं कि किन परिस्थितियों में लेबल "इंटरैक्टिव" आपके द्वारा शुरू किए गए शेल पर लागू होता है। वे कार्रवाई परिभाषा नहीं हैं क्योंकि वे इस लेबल का कोई निहितार्थ नहीं देते हैं ।
हालाँकि, मैं देख रहा हूँ कि पूरे बाश मैन पेज पर शेल के संदर्भ में कुछ विशिष्ट तरीकों से व्यवहार किया गया है "जब तक कि यह एक इंटरैक्टिव शेल नहीं है" या "केवल इंटरैक्टिव शेल में, या यदि _____ विकल्प सेट है।" (कई उदाहरण हैं और यह इस सवाल का मुख्य बिंदु नहीं है।)
इसलिए मैं स्वीकार करूंगा कि "इंटरैक्टिव" बाकी मैन पेज पर वर्णित डिफ़ॉल्ट "इंटरैक्टिव" व्यवहार (विकल्प सेटिंग्स) के संग्रह के लिए एक सुविधाजनक लेबल है। यह अपने आप में एक मौलिक शब्द या वस्तु नहीं है; शेल के स्रोत कोड के बाहर इसकी कोई आधिकारिक परिभाषा नहीं है। (उदाहरण के लिए, उदाहरण के लिए, "ओपन फाइल डिस्क्रिप्टर" या "रुकी हुई प्रक्रिया" शब्द जो कर्नेल के डिज़ाइन में निर्मित अमूर्तता को संदर्भित करता है।)
(जबकि यह उस POSIX परिभाषा में भी परिभाषित किया गया है sh
, उस आदमी पृष्ठ [ man 1p sh
] के "जब तक कि शैल संवादात्मक नहीं है" के बहुत कम उपयोग होते हैं और इसी तरह के बयान man bash
, और लगभग विशेष रूप से आह्वान-समय के अंतर पर ध्यान केंद्रित करते हैं, इसलिए मैं बैश पर ध्यान केंद्रित करूंगा। इस बिंदु से आगे।)
शेल के "इंटरएक्टिव" होने के कुछ निहितार्थ वैसे भी केवल आह्वान के समय ही प्रासंगिक होते हैं , जैसे अन्य कमांड पढ़ने से पहले शेल द्वारा फाइल को सीज़ किया जाता है। हालांकि, वहाँ रहे हैं निहितार्थ (कम से कम बैश में) है कि किसी भी समय प्रासंगिक हैं। इस प्रकार यह बताने का एक तरीका होना चाहिए कि किसी भी दिए गए रनिंग शेल के लिए, यह इंटरएक्टिव है या नहीं।
set +i
एक इंटरैक्टिव बैश शेल में चलने के कारण 'i' को सामग्री से हटा दिया जाता है $-
।
सवाल यह है कि क्या इसका मतलब यह है कि शेल अब इंटरएक्टिव नहीं है?
बैश की सटीक परिभाषा के अनुसार, यह नहीं होना चाहिए, क्योंकि परिभाषा में कहीं भी यह आवश्यक नहीं है कि 'मैं' में मौजूद हो $-
:
An interactive shell is one started without non-option arguments and without the -c option whose standard input and error are both connected to terminals (as determined by isatty(3)), or one started with the -i option.
सटीक परिभाषा के एक सख्त पढ़ने से यह सवाल भी उठता है: यदि इंटरएक्टिव टर्मिनल के स्टडिन या स्टैडर को पुनर्निर्देशित किया जाता है, तो वे अब टर्मिनलों से जुड़े नहीं हैं, तो क्या शेल गैर-इंटरैक्टिव है?
(ऐसा प्रतीत होता है कि इस एक का उत्तर "नहीं" है और मैन पेज में संशोधक शामिल हो सकता है: "जिनके मानक इनपुट और त्रुटि दोनों टर्मिनलों से जुड़े हैं ... आह्वान के समय, " लेकिन मुझे नहीं पता निश्चित।)
यदि उत्तर है, "नहीं, शेल गैर-संवादात्मक नहीं बन सकता है, न ही इसके विपरीत," तो यह निर्धारित करने का निश्चित तरीका क्या है कि शेल इंटरैक्टिव है या नहीं?
अभी तक एक और तरीका रखो: अगर एक "इंटरेक्टिव शेल" का व्यवहार होता है जो बाद में बना रहता है set +i
, तो यह निर्धारित करने के लिए क्या प्रयोग किया जाता है कि उन व्यवहारों को लागू करना जारी रखना चाहिए?
किसी को यह संदेह नहीं है: एक शैल के व्यवहार हैं जो संवादात्मक रूप से आह्वान किए गए हैं जो बाद में बने रहते हैं set +i
और एक खोल के व्यवहार गैर-अंतःक्रियात्मक रूप से आह्वान करते हैं जो बाद में बने रहते हैं set -i
। एक उदाहरण के लिए, निम्नलिखित अंश पर विचार करें man bash
:
COMMENTS In a non-interactive shell, or an interactive shell in which the inter- active_comments option to the shopt builtin is enabled (see SHELL BUILTIN COMMANDS below), a word beginning with # causes that word and all remaining characters on that line to be ignored. An interactive shell without the interactive_comments option enabled does not allow comments. The interactive_comments option is on by default in interac- tive shells.
इस प्रकार interactive_comments
विकल्प को परेशान करके हम इंटरैक्टिव और गैर-इंटरैक्टिव गोले के बीच अंतर देख सकते हैं। इस अंतर की दृढ़ता निम्न स्क्रिप्ट द्वारा प्रदर्शित होती है:
#!/bin/bash
# When the testfile is run interactively,
# all three comments will produce an error
# (even the third where 'i' is not in '$-').
# When run noninteractively, NO comment will
# produce an error, though the second comment
# is run while 'i' IS in '$-'.
cat >testfile <<'EOF'
shopt interactive_comments
shopt -u interactive_comments
shopt interactive_comments
echo $-
#first test comment
set -i
echo $-
#second test comment
set +i
echo $-
#third test comment
EOF
echo 'running bash -i <testfile'
bash -i <testfile
echo 'running bash <testfile'
bash <testfile
यह पुष्टि करता है कि "इंटरैक्टिव" और " i
के मूल्य में $-
" बराबर नहीं हैं ।
एक ${parameter:?word}
असमान पैरामीटर के साथ एक समान परीक्षण का उपयोग समान परिणाम उत्पन्न करता है, फिर से पुष्टि करता $-
है कि शेल इंटरैक्शन के लिए "सत्य का स्रोत" नहीं है।
तो, अंत में, एक खोल के निश्चित 'अन्तरक्रियाशीलता' गुण को कहाँ संग्रहीत किया जाता है?
और, क्या एक इंटरैक्टिव शेल गैर-इंटरैक्टिव या इसके विपरीत बन सकता है? (... इस विशेषता को बदलकर?)