स्क्रिप्ट से टर्मिनल की पहचान कैसे करें?


8

और मत कहो " $TERM" - यह हमेशा है xterm

कोई bashस्क्रिप्ट कैसे बता सकती है कि वह किस टर्मिनल में चल रही है, विशेष रूप से यह iTerm, Terminal.app या वास्तव में एक xterm है या नहीं?

मैं पूछता हूं क्योंकि resetटर्मिनल.app और iTerm2 पर बॉक्स से बाहर काम नहीं करता है। iTerm2, हालांकि, टर्मिनल रीसेट ( \x1b]50;ClearScrollback\x07) करने के लिए भागने के क्रम को पहचानता है , और अगर मैं इसका पता लगा सकता हूं, तो मैं resetएक उपनाम के साथ ओवरराइड कर सकता हूं जो सही काम करता है। AFAICT, Terminal.app में रीसेट अनुक्रम का अभाव है, और लोग उस के आसपास हैक करने के लिए हास्यास्पद टॉम-हैकरी का सहारा लेते हैं

यहां मेरा अंतिम लक्ष्य resetवही काम करना है, चाहे मैं ओएस एक्स या लिनक्स पर काम कर रहा हूं, स्थानीय रूप से काम कर रहा हूं या एसएसएच के माध्यम से दूरस्थ रूप से काम कर रहा हूं। (मैं यह याद रखने की कोशिश नहीं करना चाहता कि कौन सा है, और यह reset && command-that-outputs-a-bunchकाम करने के लिए उपयोगी है और अप-एंट्री कार्य है।) Terminal.app और iTerm resetसही तरीके से लागू नहीं करके इस योजना में एक रिंच फेंक रहे हैं ।

इसका मतलब यह है कि बस ओवरराइडिंग resetयह काफी नहीं है: अगर मैं लिनक्स मशीन पर हूं, तो यह जानना आवश्यक है कि मैं gnome-terminalसही भागने के क्रम को भेजने के लिए उपयोग कर रहा हूं या iTerm।

क्या कोई रास्ता है (भले ही मुझे ज़रूरत है ioctl) टर्मिनल से यह पूछने के लिए कि यह वास्तव में क्या है?

, इस प्रश्न के प्रयोजनों के लिए, स्क्रीन को रीसेट करना चाहिए, कर्सर को रीसेट करना चाहिए, और स्क्रॉलबैक बफर को मिटा देना चाहिए।


खैर, यह एक विशेषता है, बग नहीं, या इसलिए वे कहते हैं। यदि आप Terminal.appसेटिंग, टर्मिनल टैब और स्क्रोलबैक लाइन्स को 0 पर खोलते हैं तो क्या होगा ? क्या यह वर्तमान लाइन के ऊपर किसी भी और सभी पाठ को अक्षम करता है, या स्क्रीन के शीर्ष के ऊपर कुछ भी? मुझे पता है, यह बिल्कुल वैसा नहीं है जैसा आपने पूछा था, एक शॉट के लायक।
नाइट्रो 2k01

@ nitro2k01: मुझे यकीन नहीं है कि क्या पूरा होगा? मैं चाहता हूँ स्क्रॉल बैक। मैं अभी इसे स्पष्ट रूप से और फिर, अधिमानतः के साथ स्पष्ट करना चाहता हूं reset, क्योंकि मेरी उंगलियों को पता है।
थानाटोस 19

अपने "रीसेट" मुद्दे के रूप में: स्पष्ट करने के लिए, आप resetटर्मिनल इम्यूलेटर के स्क्रॉल-बैक सामग्री को साफ़ करने के लिए कमांड की अपेक्षा कर रहे हैं , लेकिन ऐसा करने की गारंटी नहीं है, क्योंकि स्क्रॉल-बैक एक टर्मिनल एमुलेटर-विशिष्ट सुविधा है, वास्तव में नहीं एक टर्मिनल का हिस्सा। हालांकि, टर्मिनल स्क्रॉल-बैक को मिटाने के लिए ED (Erase in Display) एस्केप सीक्वेंस के विस्तार का समर्थन करता है ESC [ 3 J। आप स्क्रीन को साफ़ कर सकते हैं, फिर उसका उपयोग कर सकते हैं, जैसे,reset && printf '\e[3J’
क्रिस पेज

डिस्प्ले एक्सटेंशन में इरेज़ के बारे में अधिक जानकारी के लिए मेरा जवाब यहाँ देखें apple.stackexchange.com/a/113168/6883
क्रिस पेज

@ChrisPage: मुझे एहसास है कि टर्मिनली विचित्र चीजें हैं, लेकिन अगर आप अपने आप को एक xterm(के माध्यम से TERM=xterm) घोषित करते हैं तो मैं उम्मीद करूंगा कि आप एक्सटर्म के एक सुपरसेट का अनुकरण करें, जो रीसेट पर अपने स्क्रॉलबैक को साफ करता है। (जैसे कि यदि आपने "ब्लू" के लिए एस्केप सीक्वेंस भेजा है, तो आप नीले रंग की अपेक्षा करेंगे।) दी, मेरे एक्सटरम ने मुझे बताया Erase is backspace., जो कि मैं आभारी हूं और कुछ नहीं करता; यह सिर्फ गुस्सा है।
थानाटोस

जवाबों:


10

का उपयोग करें $TERM_PROGRAM

iTerm इसे करने के लिए सेट करता है iTerm.app, और Terminal.app to Apple_Terminal


हे, ठीक है, यह स्पष्ट रूप से मेरी हैक से बेहतर है, +1 :)। हैक को किसी भी टर्मिनल एमुलेटर के लिए काम करना चाहिए, हालांकि उन दो को ही नहीं।
टेराडन

हर टर्मिनल एमुलेटर का पता लगाने का कोई एक तरीका नहीं है। उदाहरण के लिए, आप $ XTERM_VERSION चर के लिए जाँच कर सकते हैं। OS X पर संभवतः तीन सबसे लोकप्रिय एमुलेटर क्या हैं, इस पर ध्यान दिया जाएगा।
क्रिस पेज

इसे स्वीकार करना, क्योंकि यह एक अच्छी शुरुआत है। दुर्भाग्य से, यह काफी आसान नहीं है, क्योंकि यह चर SSH सत्र के अंदर उपलब्ध नहीं है। मुझे संदेह है कि ऐसे कॉन्फ़िगर हैं जो मैं इसे अग्रेषित करने के लिए संपादित कर सकता हूं।
थानाटोस

1
@Thanatos sshd_config'एस AcceptEnvशायद। जैसा कि यह (आपका शेल आपके द्वारा चलाए जा रहे एक से अधिक होस्ट पर चलता है) बहुत महत्वपूर्ण जानकारी है, यह वास्तव में प्रश्न का हिस्सा होना चाहिए।
डैनियल बेक

@ डैनियलबेक: यह सख्ती से मामला नहीं है; मैं स्थानीय और दूरस्थ रूप से ऐसा ही करना चाहूंगा। जो मैं करने जा रहा हूं, वह यह है कि टर्मिनल में "रीसेट" टाइप करने से टर्मिनल का रीसेट हो जाता है, चाहे मैं ओएस एक्स या लिनक्स पर हूं, स्थानीय या दूरस्थ रूप से काम कर रहा हूं। मैंने इसे प्रश्न में संपादित किया है।
थानाटोस

1

$TERMवर्तमान में चल रहे टर्मिनल एमुलेटर के साथ करने के लिए कुछ भी नहीं है, यह सिर्फ आपका डिफ़ॉल्ट टर्मिनल है और इसे कुछ भी करने के लिए सेट किया जा सकता है। आपके द्वारा चलाए जा रहे टर्मिनल एमुलेटर का नाम पाने के लिए, आप psअपने वर्तमान शेल की मूल प्रक्रिया के PID का उपयोग कर सकते हैं ।

नोट: निम्नलिखित OSX पर विफल हो जाएगा, लेकिन लिनक्स पर ठीक काम करना चाहिए

आपके वर्तमान शेल प्रक्रिया का पीआईडी ​​है $$। वहां से, आप psएक प्रक्रिया ट्री दिखाने के लिए उपयोग कर सकते हैं , और अपने वर्तमान शेल सत्र के माता-पिता के पीआईडी ​​को प्रिंट कर सकते हैं :

ps -axjf | awk -v pid=$$ '($2==pid){print $1}'

फिर आप उस PID को पास कर सकते हैं psऔर उसे कमांड नाम प्रिंट करने के लिए कह सकते हैं:

ps -o comm=  $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}')

यह नाम को छोटा कर देगा, आपके लिए यह पता लगाने के लिए पर्याप्त होना चाहिए लेकिन स्क्रिप्टिंग के लिए अच्छा नहीं हो सकता है। पूरा नाम पाने के लिए, आप कोशिश कर सकते हैं

ps --no-headers $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}') | awk '{print $NF}'

यह कुछ अलग टर्मिनलों का उपयोग करके मुझे अपने सिस्टम पर मिलता है:

  1. terminator

    $ ps --no-headers $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}') | 
       awk '{print $NF}'
    /usr/bin/x-terminal-emulator
    
  2. gnome-terminal

    $ ps --no-headers $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}') | 
       awk '{print $NF}'
    /usr/lib/gnome-terminal/gnome-terminal-server
    
  3. xterm

    $ ps --no-headers $(ps axjf | awk -v pid=$$ '($2==pid){print $1}') | 
       awk '{print $NF}'
    xterm
    

: ओएस एक्स पर काम नहीं करता हैps: illegal option -- f
डैनियल बेक

@DanielBeck डार BSD शैली, धन्यवाद। क्या आप अपडेट किए गए संस्करण के साथ फिर से कोशिश कर सकते हैं? -विकल्पों में से पहले जोड़ना OSX के अनुसार काम करना चाहिए man ps
टेराडन

बेहतर है, लेकिन अभी भी काम नहीं कर रहा है। आउटपुट स्वरूप अलग है (PID है $2, PPID है $3), और शेल की मूल प्रक्रिया login(अलग अलग टर्मिनल के साथ) टर्मिनल विन्यास के आधार पर हो सकती है । हालाँकि, इसकी मूल प्रक्रिया है Terminal--no-headersमौजूद नहीं है, आपको कुछ ऐसा चाहिए होगा tail -n1। और चूंकि UI के साथ सभी प्रक्रियाओं में एक तर्क है-psn_0_... , awk '{print $NF}'या तो काम नहीं करता है।
डैनियल बेक

@DanielBeck तो अच्छी तरह से shucks। ठीक है, धन्यवाद मैं यह स्पष्ट कर दूंगा कि यह OSX पर विफल है।
टेराडॉन

ध्यान दें कि यह केवल स्थानीय रूप से काम करता है। आप इस दृष्टिकोण का उपयोग यह पता लगाने के लिए नहीं कर सकते हैं कि रिमोट क्लाइंट पर टर्मिनल एमुलेटर का क्या उपयोग किया जा रहा है। सबसे अच्छा जवाब $ TERM_PROGRAM (@ DanielBeck के जवाब में उल्लिखित) और $ XTERM_VERSION जैसे वेरिएबल को देखने के लिए एमुलेटर एप्लिकेशन को कम करना है।
क्रिस पेज

0

मूल प्रक्रिया का नाम या पथ प्राप्त करने का एक पोर्टेबल तरीका यहां दिया गया है:

iTerm 2:

$ ps -p $(ps -p $$ -o ppid=) -o comm=
/Applications/iTerm.app/Contents/MacOS/iTerm

Ubuntu में सूक्ति-टर्मिनल:

$ ps -p $(ps -p $$ -o ppid=) -o comm=
gnome-terminal

Terminal.app:

$ ps -p $(ps -p $$ -o ppid=) -o comm=
login

ध्यान दें कि यदि टर्मिनल.app डिफ़ॉल्ट लॉगिन शेल के साथ नए शेल खोलने के लिए सेट है, तो शेल की मूल प्रक्रिया loginटर्मिनल है और नहीं।

commस्तंभ ओएस एक्स में कमान और आदेश नाम लिनक्स में procps कार्यान्वयन में 15 वर्ण तक छोटा कर दिया का पूरा पथ है।


ITerm में कोशिश की और मिल गया login- क्या मैंने कमांड चलाने के लिए कुछ समय पहले अपनी प्रोफ़ाइल को अनुकूलित किया था login -fp danielbeck?
डैनियल बेक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.