क्या एक इंटरैक्टिव शेल गैर-इंटरैक्टिव या इसके विपरीत बन सकता है?


16

क्या एक इंटरैक्टिव शेल गैर-इंटरैक्टिव या इसके विपरीत बन सकता है?

नोट: मैंने मूल प्रश्न पर बहुत सारे शोध किए हैं, "इंटरैक्टिव और गैर-इंटरैक्टिव के बीच अंतर क्या है?", और मेरे शोध के परिणामों ने मुझे यह सवाल पूछा।

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


में man 1p sh, एक इंटरैक्टिव खोल के निम्नलिखित परिभाषा दी गई है:

   If the -i option is present, or  if  there  are  no  operands  and  the
   shells  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}असमान पैरामीटर के साथ एक समान परीक्षण का उपयोग समान परिणाम उत्पन्न करता है, फिर से पुष्टि करता $-है कि शेल इंटरैक्शन के लिए "सत्य का स्रोत" नहीं है।


तो, अंत में, एक खोल के निश्चित 'अन्तरक्रियाशीलता' गुण को कहाँ संग्रहीत किया जाता है?

और, क्या एक इंटरैक्टिव शेल गैर-इंटरैक्टिव या इसके विपरीत बन सकता है? (... इस विशेषता को बदलकर?)


जवाबों:


9

सवाल मैं पूछना होगा कि कोई भी ऐसा क्यों करना चाहेगा?

आप इंटरैक्टिव गोले के कुछ पहलुओं को निष्क्रिय कर सकते हैं जैसे:

  • PS1= PS2= संकेतों को निष्क्रिय करने के लिए
  • set +m नौकरी नियंत्रण को निष्क्रिय करने के लिए
  • कुछ गोले में इतिहास को निष्क्रिय करें
  • आप zleसभी और सभी पूर्ण मॉड्यूल को अनलोड करने में सक्षम हो सकते हैं zsh

लेकिन अगर आप चाहते हैं कि शेल इंटरएक्टिव होने से रुक जाए, तो आप इसके बजाय कर सकते हैं:

. /some/file; exit

यह बताने के लिए कि बाकी आज्ञाओं को प्राप्त करने के लिए /some/file( /dev/ttyयदि आप अभी भी आदेशों को टैटी डिवाइस से पढ़ना चाहते हैं) से प्राप्त करें, हालांकि गैर-संवादात्मक गोले से कुछ अंतर होंगे, जैसे कि returnया तथ्य के व्यवहार के लिए यह अभी भी नौकरी पर नियंत्रण या करेगा:

exec myshell /dev/tty

अपने वर्तमान इंटरेक्टिव शेल को एक गैर-इंटरैक्टिव वाले के साथ बदलने के लिए जो अभी भी ट्टी डिवाइस से कमांड पढ़ता है।

ध्यान दें कि बैश 4.4 के साथ, अधिकांश अन्य गोले की तरह set +iवापस आता है bash: set: +i: invalid option


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

1
@Wildcard, यदि आप exec < <(sleep infinity)एक इंटरैक्टिव शेल में करते हैं, तो आपको एक इंटरैक्टिव शेल मिला है जो बहुत इंटरैक्टिव नहीं है। खोल अभी भी अपने आप को उस में इंटरएक्टिव $-समझेगा जिसमें अभी भी शामिल होगा i, लेकिन आप नहीं हो सकते। मुझे यकीन नहीं है कि इसके बारे में चर्चा करने के लिए बहुत कुछ है।
स्टीफन चेज़लस

2
@Wildcard, अगर खोल के रूप में शुरू किया गया था interactive, यह ऐसा ही रहता है। तथ्य यह है कि आप set +iपुराने बैश संस्करणों में कर सकते थे एक बग था।
स्टीफन चेजलस

1
@Wildcard, यदि आप के स्रोत कोड को देखते हैं bash, तो आप शायद पाएंगे कि एक interactiveवैश्विक बूलियन चर है जो कि iध्वज के नक्शे पर है $-। उस बूलियन को बदलना स्वचालित रूप से इंटरेक्टिव गोले के सभी व्यवहारों को नहीं बदलेगा। इंटरैक्टिव से गैर-इंटरएक्टिव में परिवर्तन का समर्थन नहीं किया जाता है।
स्टीफन चेज़लस

4
@Wildcard डैश स्वीकार करता है set +iऔर एक संकेत प्रदर्शित करना बंद कर देता है। यह कुछ ऐसा है जिसे उपयोगकर्ता करने वाला नहीं है, इसलिए यह आश्चर्य की बात नहीं है कि शेल पर व्यवहार निर्भर करता है और शेल कार्यान्वयनकर्ता द्वारा जानबूझकर निर्णय लेने के परिणामस्वरूप अक्सर आकस्मिक होता है।
गाइल्स का SO- बुराई से दूर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.