मैं कैसे जांच सकता हूं कि मेरा शेल टर्मिनल में चल रहा है या नहीं?


22

मैं कुछ कार्रवाई तभी करना चाहता हूं जब मेरा शेल टर्मिनल से "जुड़ा हुआ" है, केवल तभी जब मेरा मानक इनपुट टर्मिनल के इनपुट और मेरे मानक आउटपुट (और मानक त्रुटि से आता है? शायद यह कोई फर्क नहीं पड़ता) मुद्रित / गूंज जाता है? एक टर्मिनल।

/proc/selfसीधे जीएनयू / लिनक्स की बारीकियों (जैसे ) पर भरोसा किए बिना मैं ऐसा कैसे कर सकता हूं ?


जवाबों:


33

isattyयह जाँचने के लिए एक फ़ंक्शन है , और कमांड का -tध्वजtest शेल स्क्रिप्ट से सुलभ है:

-t file_descriptor

फ़ाइल डिस्क्रिप्टर नंबर file_descriptor खुला है और एक टर्मिनल के साथ जुड़ा हुआ है तो सही है। गलत अगर file_descriptor एक मान्य फ़ाइल डिस्क्रिप्टर नंबर नहीं है, या यदि फ़ाइल डिस्क्रिप्टर नंबर file_descriptor खुला नहीं है, या यदि यह खुला है, लेकिन टर्मिनल से जुड़ा नहीं है।

आप देख सकते हैं कि FD 0 (मानक इनपुट) एक TTY है:

test -t 0

आप एफडी 1 और 2 के लिए आउटपुट और त्रुटि धाराओं, या उन सभी की जांच करने के लिए ऐसा कर सकते हैं:

test -t 0 -a -t 1 -a -t 2

यदि डिस्क्रिप्टर एक टर्मिनल तक झुका हुआ है, और अन्यथा गलत है, तो कमांड 0 (सफल) हो जाती है।

test["ब्रैकेट टेस्ट" के लिए कमांड के रूप में भी उपलब्ध है :

 if [ -t 0 ] ; then ...

यह सशर्त लिखने का एक मुहावरेदार तरीका है।


8

मुझे लगता है कि यह एक डुप्लिकेट है, लेकिन मैं इसे नहीं ढूंढ सकता। उपयोग

[ -t 0 ]

तथा

[ -t 1 ]

परीक्षण करने के लिए कि क्या मानक इनपुट और आउटपुट एक टर्मिनल से जुड़े हैं। man testविवरण है।


7

पहले से दिए गए ठीक उत्तरों के शीर्ष पर सिर्फ एक अतिरिक्त नोट। ध्यान दें कि [ -t 0 ]फ़ाइल डिस्क्रिप्टर 0 का परीक्षण एक फाइल को खोलने वाला है, जो एक डिवाइस फ़ाइल है, जो ट्टी लाइन डिसिप्लिन के साथ है (आम तौर पर, यह जाँच कर के किया जाता है कि हानिरहित टर्मियो (एस) ioctl () सफल होता है)।

इसके अलावा, इसका मतलब यह नहीं है कि दूसरे छोर पर एक टर्मिनल या टर्मिनल एमुलेटर (एक कीबोर्ड पर वास्तविक उपयोगकर्ता टाइपिंग के साथ) है (हालांकि अधिकांश मामलों में और शायद आप की देखभाल करने वाले अधिकांश लोग, यह काफी अच्छा है अनुमान)।

ट्टी और पीटीआई उपकरणों का उपयोग डेटा ट्रांसफर के लिए या इंटरप्रोसेस संचार तंत्र के रूप में भी किया जा सकता है।

उदाहरण के लिए, कोई भी ऐसा कर सकता है:

(stty raw -echo; myscript) < /dev/ttyS0

RS232 पर प्राप्त करने के लिए फ़ीड करने के लिए myscript

echo test | ssh -tt host myscript

होता myscriptहै stdin एक प्राइवेट डिवाइस जा रहा है (के साथ sshdदूसरे छोर पर है, और अंततः (ssh कनेक्शन भर में) नहीं एक टर्मिनल है, लेकिन एक पाइप से तंग आ गया echo)

यह जांचने के लिए कि उस RS232 लाइन या पीटीआई के दूसरे छोर पर एक टर्मिनल है, आप यह भी देख सकते हैं कि एक $TERMचर सेट किया गया है और गैर-खाली है ( [ -n "$TERM" ]) और उस fd पर एक डिवाइस स्टेटस रिपोर्ट एस्केप सीक्वेंस भेजें और प्राप्त करें की जांच करें एक प्रतिक्रिया (के अलावा [ -t 0 ]और [ -n "$TERM" ])।

printf >&0 '\e[5n'

\e[0nसबसे टर्मिनलों द्वारा उत्तर दिया गया है ।

अब इसके साथ कई समस्याएं हैं, इसलिए मैं यह करने की सलाह नहीं दूंगा कि आप उस मामले को छोड़कर जहां आप यह जांचना चाहते हैं कि आप दृश्य TUI एप्लिकेशन चलाना चाहते हैं (किस स्थिति में, आप पुस्तकालयों का उपयोग करना बेहतर होगा ncurses, जैसे , और डीएसआर के बजाय, आप टर्मिनल के प्रकार के माध्यम से अधिक सटीक तरीके से क्वेरी करने के लिए उपकरण पहचान एस्केप अनुक्रम भेजना चाहेंगे $TERM):

  • शुक्र है, ज्यादातर मामलों में जहां स्टडिन एक टर्मिनल नहीं है, यह रीड-ओनली मोड में खुला होता है, जिसके कारण यह printfविफल हो जाता है, लेकिन अगर स्टडी रीड + राइट मोड में खुली डिवाइस है, तो इसका साइड इफेक्ट होगा। उस क्रम को दूसरे छोर पर भेजना। उदाहरण के लिए हमारे ssh उदाहरण में, कि वास्तव में एक टर्मिनल के लिए अनुक्रम भेज देंगे (लेकिन उत्तर stdin पर नहीं आ जाएगा)
  • उत्तर को मज़बूती और आंशिक रूप से पढ़ना कठिन है। आपको अस्थायी रूप से टेट लाइन अनुशासन को बदलने और एक बार में एक बाइट पढ़ने की आवश्यकता होगी। आपको एक टाइमआउट तय करने की भी आवश्यकता होगी जिसके द्वारा यदि उत्तर नहीं देखा जाता है, तो आप हार मान लेते हैं और निर्णय लेते हैं कि कोई टर्मिनल नहीं है। यदि आप सैटेलाइट कनेक्शन पर डायल करने वाले लोगों पर विचार करना चाहते हैं, तो इसका मतलब है कि एक लंबा समय।
  • एक टर्मिनल से पढ़ना जब पृष्ठभूमि में SIGTTIN संकेत के साथ आपकी स्क्रिप्ट को निलंबित कर देगा।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.