कैसे जाँचें कि कोई शेल लॉगिन / इंटरेक्टिव / बैच है या नहीं


143

मुझे लगता है कि मैं एक इंटरैक्टिव, एक लॉगिन और एक बैच शेल के बीच अंतर को समझता हूं। अधिक मदद के लिए निम्न लिंक देखें:

मेरा सवाल यह है कि अगर मैं एक इंटरैक्टिव, एक लॉगिन या बैच शेल पर हूं, तो मैं कमांड / स्थिति के साथ कैसे परीक्षण कर सकता हूं?

मैं एक कमांड या स्थिति (जो रिटर्न trueया false) के लिए देख रहा हूं और यह कि मैं एक स्टेटमेंट पर भी जगह बना सकता हूं। उदाहरण के लिए:

if [[ condition ]]
   echo "This is a login shell"
fi

3
अभी तक एक और सवाल है: क्या स्टैटिन और / या STDOUT एक ट्टी (टर्मिनल) या एक पाइप (फ़ाइल या प्रक्रिया) से जुड़े हैं? यह एक संबंधित लेकिन अलग-अलग परीक्षण है जैसा कि नीचे दी गई कुछ टिप्पणियों में वर्णित है।
मार्क हडसन

जवाबों:


160

मैं एक bashशेल या समान मान रहा हूं , क्योंकि टैग में कोई शेल सूचीबद्ध नहीं है।

यह देखने के लिए कि क्या आप एक इंटरैक्टिव शेल में हैं:

[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'

यह देखने के लिए कि क्या आप एक लॉगिन शेल में हैं:

shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'

"बैच" द्वारा, मेरा मानना ​​है कि आप "इंटरएक्टिव नहीं" हैं, इसलिए एक इंटरैक्टिव शेल के लिए चेक पर्याप्त होना चाहिए।


12
के लिए zshउपयोगकर्ताओं, एक लॉगिन खोल के लिए जाँच के साथ किया जा सकता है:if [[ -o login ]] ...
chb

1
यदि आप जानना चाहते हैं कि क्या "उपयोगकर्ता" ने आपका प्रोग्राम बनाम "क्रोन" चलाया है। [[अवधि == "गूंगा"] && गूंज "क्रोन में चल रहा है।
एरिक एरोनिटी

10
@ ErikAronesty सभी गूंगे टर्मिनल क्रोन सत्र नहीं हैं।
क्रिस डाउन

2
"मैं बैश शेल मान रहा हूं, या इसी तरह, क्योंकि टैग में कोई शेल सूचीबद्ध नहीं है।" - इस कथन का तर्क वास्तव में सुंदर है! :)
माइकल ले बारबियर ग्रुएनवाल्ड

2
@antonio ऐसा इसलिए है क्योंकि आपका उद्धरण गलत है, $-वर्तमान शेल में विस्तारित किया जा रहा है। यदि आप पूर्ण अभिव्यक्ति के आसपास एकल उद्धरण का उपयोग करते हैं तो आपको सही परिणाम मिलेगा:bash -c '[[ $- == *i* ]] && echo "Interactive" || echo "Not interactive"'
क्रिस डाउन

33

किसी भी बॉर्न-शैली शेल में, iविकल्प इंगित करता है कि शेल इंटरैक्टिव है या नहीं:

case $- in
  *i*) echo "This shell is interactive";;
  *) echo "This is a script";;
esac

लॉगिन शेल के लिए परीक्षण करने के लिए कोई पोर्टेबल और पूरी तरह से विश्वसनीय तरीका नहीं है। Ksh और zsh को जोड़ते lहैं $-। बैश login_shellविकल्प सेट करता है, जिसे आप क्वेरी कर सकते हैं shopt -q login_shell। आंशिक रूप से, परीक्षण करें कि क्या $0शुरू होता है -: गोले सामान्य रूप से जानते हैं कि वे लॉगिन गोले हैं क्योंकि कॉलर ने -तर्क को शून्य में जोड़ दिया (सामान्यतः निष्पादन का नाम या पथ)। यह लॉगिन शेल (जैसे ash -l) को लागू करने के शेल-विशिष्ट तरीकों का पता लगाने में विफल रहता है ।


(...) क्योंकि फोन करने वाले - मुझे लगता है कि इस टुकड़े में कुछ गायब है।
पायोटर डोब्रोगोस्ट

यह आदर्श होगा यदि $0हमेशा -कोई फर्क नहीं पड़ता कि यह कैसे शुरू किया गया था। लेकिन कम से कम एक अपवाद है: यह हमेशा बैश के साथ सच नहीं है, भले ही यह एक लॉगिन शेल माना जाता हो। इसे अपने बॉक्स में आज़माएँ: आह्वान करें bash --login, फिर $0भी पढ़ता है bash
वाईरवान पुरवंतो

@IrawanPurwanto मुझे यकीन नहीं है कि मैं आपकी टिप्पणी को समझ सकता हूँ। क्या ऐसा नहीं है जो मैंने अपने आखिरी वाक्य में लिखा है?
गिल्स

@ गिल्स: आप सही हैं। क्षमा करें, मैंने आपका अंतिम वाक्य याद किया।
विरवान पुरवंतो

24

मछली का खोल

fishयदि कोई अन्य उपयोगकर्ता इस पृष्ठ पर ठोकर खाता है, तो इसका उत्तर यहां है ।

if status --is-interactive
    # ...
end

if status --is-login
    # ...
end

echo "darn, I really wanted to have to use globs or at least a case statement"

मछली प्रलेखन: आरंभीकरण


1
-1 अनावश्यक संपादकीय के लिए।
निक बैस्टिन

6
यदि कोई भी @ NickBastin की टिप्पणी पर आश्चर्य करता है, तो उसके पास एक उचित बिंदु था इसलिए मैंने एक संपादन किया। स्नार्कनेस की मूल मात्रा अब आधी हो गई है।
3

18

csh / tcsh

के लिए cshऔर tcshमैं अपने में निम्नलिखित है .cshrcफ़ाइल:

if($?prompt) then               # Only interactive shells set $prompt
    ...
endif

विशेष रूप से tcsh, चर loginshएक लॉगिन शेल के लिए सेट किया गया है:

if($?loginsh) then              # A login shell..
    ...
endif

( tcshएक चर भी है shlvlजो नेस्टेड शेल की संख्या पर सेट है, जहां लॉगिन शेल का मान 1 है।)


2
PS1एक इंटरैक्टिव शेल के लिए परीक्षण करने के लिए काम नहीं करता है। यह लगभग हमेशा एक इंटरैक्टिव में सेट होता है, लेकिन आप इसे परेशान कर सकते हैं। यह बहुत बार एक गैर-सक्रिय शेल में सेट होता है, क्योंकि कई सिस्टम में जहाज होते export PSहैं /etc/profile
गिल्स

@ गिल्स सुधार के लिए धन्यवाद और संपादित करें
एंड्रयू स्टीन

17

एक और तरीका है के परिणाम की जाँच करें tty

if [ "`tty`" != "not a tty" ]; then

10
... या [ -t 0 ]परीक्षण करने के लिए उपयोग करें कि क्या एसटीडीआईएन टटी है। आप अपनी आवश्यकताओं के आधार पर 1 (STDOUT) या 2 (STDERR) का भी उपयोग कर सकते हैं।
derobert


10
यह एक अलग परीक्षा है। एक गैर-सक्रिय शेल का होना संभव है जिसका इनपुट एक टर्मिनल है (कभी-कभी आप किसी स्क्रिप्ट को टर्मिनल में चलाते हैं!), और यह संभव है (यद्यपि दुर्लभ) एक इंटरैक्टिव शेल को इनपुट लेना है जो टर्मिनल से नहीं है।
गिल्स

@Gilles यदि खोल संवादात्मक था, और एक बच्चे को छोड़ना बंद कर दिया disownऔर जीवित हो गया, तो ttyयह जानने के लिए सबसे अच्छा काम किया कि यह अब इंटरैक्टिव नहीं है, जबकि $-बदल नहीं गया; मैं अभी भी हैरान हूं कि सबसे अच्छा तरीका क्या है।
कुंभ राशि

5
@AquariusPower तब आप जो परीक्षण करना चाहते हैं वह इंटरएक्टिव शेल के लिए नहीं है, लेकिन क्या मानक इनपुट एक टर्मिनल है। का उपयोग करें [ -t 0 ]। PS मेरी पिछली टिप्पणी में, मैंने लिखा है कि "एक मजबूत सहसंबंध है" - मैं भूल गया "एक स्क्रिप्ट के अत्यंत सामान्य मामले के अलावा #!/bin/shया इसके साथ शुरू हुआ ", जो गैर-संवादात्मक है लेकिन एक टर्मिनल से जुड़ा जा सकता है।
गिल्स

8

UNIX / Linux के पास यह जांचने के लिए एक कमांड है कि क्या आप टर्मिनल पर हैं।

if tty -s
then
echo Terminal
else
echo Not on a terminal
fi

1
इसमें dashभी काम आता है ।
केन शार्प

7

आप यह देखने के लिए जांच कर सकते हैं कि क्या स्टडिन एक टर्मिनल है:

if [ -t 0 ]
then
    echo "Hit enter"
    read ans
fi

3

यह देखने के लिए कि कोई स्क्रिप्ट एक संवादात्मक या गैर-संवादात्मक शेल में चलती है, मैं अपनी स्क्रिप्ट में $PS1चर में संग्रहीत प्रांप्ट की उपस्थिति के लिए जांच करता हूं :

if [ -z $PS1 ] # no prompt?
### if [ -v PS1 ]   # On Bash 4.2+ ...
then
  # non-interactive
  ...
else
  # interactive
  ...
fi

यह मैंने यहां सीखा: https://www.tldp.org/LDP/abs/html/intandnonint.html


1

iदेखने के लिए सही विकल्प नहीं है। -iएक अन्यथा गैर-इंटरैक्टिव शेल को इंटरैक्टिव बनने के लिए मजबूर करना है। सही ऑटो-सक्षम विकल्प है -s, लेकिन बैश दुर्भाग्य से इसे सही ढंग से नहीं संभालता है।

आपको यह जांचने की आवश्यकता है कि क्या $-इसमें शामिल है s(यह स्वतः-सक्रिय होने के लिए दी गई है) या इसमें शामिल है i(यह स्वतः-सक्रिय होने की अनुमति नहीं है लेकिन आधिकारिक तौर पर केवल -iशेल के कमांड लाइन विकल्प के लिए युग्मित है )।


1
sयदि शेल स्टड से कमांड पढ़ता है, तो यह इंटरएक्टिव नहीं है। एक इंटरेक्टिव शेल आवश्यक रूप से zsh -i < /dev/nullस्टैडेन से कमांड नहीं पढ़ता है (कोशिश करें , हालांकि zsh यहां अपवाद लगता है)। और एक शेल स्टड से कमांड पढ़ सकता है और इंटरेक्टिव नहीं हो सकता (जैसे sh < fileया echo 'echo "$1"' | sh -s foo bar)।
स्टीफन चेजलस

2
जो मैं इंगित करना चाहता था वह यह है कि मूल बॉर्न शेल में $ - में 'i' नहीं है, तब भी जब यह इंटरएक्टिव होने का इरादा है।
शास्त्री

ठीक है, लेकिन यू एंड एल पर, "शेल" आधुनिक गोले को संदर्भित करता है । बॉर्न शेल को आम तौर पर एक अवशेष माना जाता है और आपका खुद का वैरिएंट मुख्यधारा नहीं है जिससे लोगों को यह पता चले कि आप किस बारे में बात कर रहे हैं, जब तक कि आप स्पष्ट नहीं करते। उल्लिखित प्रश्न [[...]]जिसका अर्थ है ksh / bash / zsh। आप एक के रूप में एक बिंदु मिल गया है इतिहास टिप्पणी है कि के लिए जाँच iमें $-बॉर्न शैल में काम नहीं करेगा। लेकिन तब जाँच के लिए sवहाँ मज़बूती से काम नहीं करेगा। आप भी [ -t 0 ]या के लिए जाँच करना चाहते हैं i; तब भी कि कोने के मामलों में मूर्ख बनाया जाएगाecho 'exec < /dev/tty; that-check' | sh'
स्टीफन Chazelas

सोलारिस 10 तक के सोलारिस मूल बॉर्न शेल के साथ आते हैं और यहां तक ​​कि sill में aprox भी शामिल है। SVr4 के बाद से शेल में 10 कीड़े ज्ञात हैं। तो बॉर्न शेल पर एक संकेत जोड़ना भयावह रूप से टोपी नहीं है जैसा कि आप विश्वास कर सकते हैं। दूसरी तरफ zsh पर्याप्त संगत नहीं है, उदाहरण के लिए, जब आप zsh के साथ "कॉन्फ़िगर" चलाने का प्रयास करते हैं, तो विफल रहता है, इसलिए zsh को इंगित करने के लिए सेट / बिन / श से सावधान रहें। BTW: मेरा बॉर्न शैल सेट -i डिफ़ॉल्ट रूप से मामले में यह इंटरैक्टिव होने का फैसला करता है।
स्किल

3
मुझे लगता है कि POSIX को $ की आवश्यकता नहीं लगती है - इसमें i (जो इसे s की आवश्यकता लगती है) है, मैं austin-group ML पर प्रश्न उठाऊंगा।
स्टीफन चेज़लस 15
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.