बैश: यह निर्धारित करने के लिए कि टर्मिनल तीसरे पक्ष के ऐप द्वारा खोला गया है या नहीं


9

मैं चाहता हूं कि मेरी बैश स्क्रिप्ट (विशेष रूप से मेरी ~/.bashrc) केवल कुछ करने के लिए अगर टर्मिनल मेरे द्वारा सीधे खोला गया था, और कुछ और करें अगर यह ऐप जैसे वीएस कोड के माध्यम से खोला गया था। मैं यह कैसे निर्धारित कर सकता हूं कि मामला क्या है? क्या इसके लिए कोई चर है? अग्रिम में धन्यवाद।


1
वहाँ एक तरह से है, मेरी पहली प्रतिक्रिया askubuntu.com/a/1042727/295286 में दूसरे उदाहरण के साथ जाना होगा । VS खोलने और envकमांड चलाने का प्रयास करें । देखें कि क्या कोई वीएस-विशिष्ट चर है जिसका हम उपयोग कर सकते हैं।
सर्गी कोलोडाज़नी 21

1
यदि कुछ नहीं है, तो इसे दूसरे तरीके से आज़माएँ: देखें कि क्या आपका टर्मिनल एमुलेटर एक चर सेट करता है। मैं उपयोग करता हूं yakuakeऔर एक चर PULSE_PROP_OVERRIDE_application.name=Yakuakeसेट xtermकरता XTERM_VERSION=XTerm(322)हूं , और मेरी मशीन पर सेट करता हूं।
मिठाई

@SergiyKolodyazhnyy क्या आप पर्यावरण चर दृष्टिकोण के लिए एक जवाब लिखेंगे?
मिठाई

@dessert मैं कर सकता हूं, लेकिन मेरे पास वीएस स्थापित नहीं है, न ही ओपी ने जवाब दिया है कि अगर कोई विशेष पर्यावरण चर है जिसे हम ले सकते हैं।
सर्गी कोलोडियाज़नी

@SergiyKolodyazhnyy न तो मेरे पास है, लेकिन प्रश्न शीर्षक तीसरे पक्ष के ऐप का कहना है और मुझे लगता है कि यह किसी भी टर्मिनल एमुलेटर की तरह ही काम करता है - मुझे लगता है कि env >env_term1एक एमुलेटर में एक उत्तर की तरह , env >env_term2एक दूसरे में और यह कैसे उपयोग करना diff env_term{1,2}है, यह कहना बहुत उपयोगी है। आखिरकार, ओपी कहता है जैसे वीएस कोड
मिठाई

जवाबों:


10

आप शायद इसे खोल के पूर्वजों की पीठ पर चढ़कर कर सकते हैं और यह काम कर सकते हैं कि क्या यह "आप", या किसी अन्य कार्यक्रम के बराबर है।

शेल की पीआईडी ​​(प्रक्रिया आईडी) प्राप्त करें, और इससे उसका पीपीआईडी ​​(मूल प्रक्रिया आईडी)। जब तक आप कुछ पाने के लिए उठते रहें जो आपको बताता है कि यह कहां से आया है। आपको अपने सिस्टम पर प्रयोग करने की आवश्यकता हो सकती है - कम से कम, मुझे नहीं पता कि यह सार्वभौमिक होगा या नहीं।

उदाहरण के लिए, मेरे सिस्टम पर, शेल की PID प्राप्त करें और psयह दिखाने के लिए उपयोग करें bash:

$ echo $$
18852
$ ps --pid 18852
  PID TTY          TIME CMD
18852 pts/1    00:00:00 bash

18852 का PPID प्राप्त करें:

$ ps -o ppid= -p 18852
18842

पीपीआईडी ​​(18842) क्या है:

$ ps --pid 18842
  PID TTY          TIME CMD
18842 ?        00:00:02 gnome-terminal

हम देख सकते हैं कि यह गनोम-टर्मिनल, यानी टर्मिनल एमुलेटर / टर्मिनल विंडो है। हो सकता है कि आपके लिए यह काफी अच्छा हो, यदि आपका प्रोग्राम दूसरे प्रोग्राम द्वारा लॉन्च किया गया है, जो टर्मिनल एमुलेटर विंडो में नहीं चल रहा है।

यदि यह पर्याप्त नहीं है, तो दूसरे स्तर पर जाएं:

$ ps -o ppid= -p 18842
 2313
$ ps --pid 2313
  PID TTY          TIME CMD
 2313 ?        00:00:00 init

यह हमें बताता है कि gnome-terminalकिसके द्वारा शुरू किया गया था init। मुझे संदेह है कि एक अन्य कार्यक्रम द्वारा शुरू किया गया आपका शेल वहां कुछ अलग होगा।


... या शायद परिणाम के रूप में चल रहा हैpstree -s $$
Steeldriver

9
"यह हमें बताता है कि गनोम-टर्मिनल की शुरुआत आईआईटी द्वारा की गई थी" मुझे लगता है कि इनिट में टर्मिनल विंडो शुरू नहीं होगी। बल्कि, जो कुछ भी शुरू हुआ, गनोम-टर्मिनल की मृत्यु हो गई, और गनोम-टर्मिनल को फिर से इन-पेरेंट किया गया। सूक्ति-टर्मिनल की जाँच, ऐसा लगता है कि यह डबल कांटे हैं। इसलिए जब यह क्रियान्वित होता है, तो यह पहली बार खुद को छोड़ देता है और नई प्रक्रिया को जारी रखता है।
जोएल

@ जोएल फेयर पॉइंट। initहालांकि यह प्रक्रिया 1 नहीं है, लेकिन यह सुनिश्चित नहीं है कि कुछ भी बदल जाएगा।
कैस्परल्ड

आपका बहुत बहुत धन्यवाद! मैं यह पता लगाने में सक्षम था कि न तो वीएस कोड और न ही ग्रहण बच्चे के रूप में टर्मिनल चलाते हैं gnome-terminal। मैंने अपनी कमान को अंजाम दिया if [ $(pstree -s $$ | grep "gnome-terminal" -c) -gt 0 ]; then ...और यह काम कर गया।
पेपरबाग

9

जहाँ तक विज़ुअल स्टूडियो कोड जाता है, वहाँ जाहिरा तौर पर एकीकृत टर्मिनल के लिए अतिरिक्त पर्यावरण चर सेट करने का एक तरीका है । तो, इस विन्यास का उपयोग करने के लिए Visual Studio सेट करें:

"terminal.integrated.env.linux": {
  "visual_studio": "true"
}

और भीतर ~/.bashrc:

if [ -n "$visual_studio" ]; then
    # do something for Visual Studio
else
    # do something else for other types of terminal
fi

सामान्य तौर पर, आप bashप्रक्रिया को दिए गए वातावरण पर भरोसा कर सकते हैं । उदाहरण के लिए, चर , और एक समान चलाने के लिए शाखा या कुछ और। केस-टू-केस के आधार पर, आप प्रत्येक कंसोल में चलने के माध्यम से पर्यावरण में अंतर की जांच कर सकते हैं , उस के रूप में फाइल करने के लिए सहेज सकते हैं , और जैसा कि टिप्पणियों में मिठाई द्वारा सुझाया गया है ।$TERMif..then...else...fi[ "$TERM" = "xterm" ]envenv > output_console1.txtdiff output_console1.txt output_console2.txt


$Env:varबैश में पर्यावरण चर के लिए वाक्य रचना नहीं है। यह मेरे लिए एक पॉवर्स की तरह दिखता है।
डायट्रिच एप्प

@DietrichEpp हाँ, मैं मूल रूप से विज़ुअल स्टूडियो में अतिरिक्त पर्यावरण चर सेट करने के तरीकों पर शोध कर रहा था, लेकिन अनदेखी की कि जवाब PowerShell का उपयोग कर रहे थे। इतना $fooकाफी है। कॉफी शायद पर्याप्त नहीं है।
सर्गी कोलोडियाज़नी

3-पार्टी प्रोग्रामों के सामान्य मामले के लिए, जिसमें एनवी-सेटिंग नहीं है, आप प्रोग्राम को चलाने से पहले एक आवरण में एक कस्टम एनवी संस्करण सेट कर सकते हैं । मेरा जवाब देखिए ।
पीटर कॉर्डेस

2

यदि आप एक विशिष्ट तृतीय-पक्ष ऐप के बारे में बात कर रहे हैं, तो एक पर्यावरण चर का उपयोग करें। अधिकांश कार्यक्रम पूरे वातावरण के साथ गुजरेंगे जब वे नई प्रक्रियाओं को कांटा + निष्पादित करेंगे।

तो, इस ऐप को एक कस्टम एनव संस्करण के साथ शुरू करें जिसे आप जांच सकते हैं । जैसे इसके लिए एक उपनाम बनाते हैं alias vs=RUNNING_FROM_VSCODE=1 VSCode, या इस तरह एक आवरण स्क्रिप्ट बनाते हैं:

#!/bin/sh
export RUNNING_FROM_VSCODE=1
exec VSCode "$@"

फिर अपने में .bashrc, तुम कर सकते हो

if (($RUNNING_FROM_VSCODE)); then
   echo "started from inside VSCode"
   # RUNNING_FROM_VSCODE=0  # optional if you only want the immediate child
fi

(( ))यदि कोई गैर-शून्य पूर्णांक (जो मैंने 1ऊपर उपयोग किया है) का मूल्यांकन करता है, तो एक बैश अंकगणितीय कथन सत्य है । खाली स्ट्रिंग (एक unset env var के लिए) गलत है। यह बाश बूलियन चर के लिए अच्छा है, लेकिन आप बस trueएक पारंपरिक पोसिक्स के साथ आसानी से इसका उपयोग और जांच कर सकते हैं

if [ "x$RUNNING_FROM_VSCODE" = "xtrue" ]; then
   echo "started from inside VSCode"
fi

यदि आपका ऐप ज्यादातर अपने बच्चों के लिए पर्यावरण को साफ करता है , लेकिन अभी भी $PATHअपरिवर्तित है, तो आप इसे अपने आवरण में उपयोग कर सकते हैं:

#!/bin/sh
export PATH="$PATH:/dev/null/RUNNING_FROM_VSCODE"
exec VSCode "$@"

और इसके लिए एक पैटर्न-मैच के साथ बैश की तरह [[ "${PATH%RUNNING_FROM_VSCODE}" != "$PATH" ]]जांच करें कि पीएटीएच से प्रत्यय बदलते हैं या नहीं।

यह हानिरहित रूप से एक अतिरिक्त निर्देशिका लुकअप करना चाहिए, जब प्रोग्राम बाहरी नहीं पाया जाता है। /dev/nullनिश्चित रूप से किसी भी प्रणाली पर एक निर्देशिका नहीं है, इसलिए यह एक फर्जी निर्देशिका के रूप में उपयोग करना सुरक्षित है जो जल्दी से परिणाम देगा ENOTDIRयदि पैथ खोजों को वे नहीं मिलेंगे जो वे पहले के पैठ प्रविष्टियों में देख रहे हैं।


रैपर स्क्रिप्ट आमतौर पर एक समझदार दृष्टिकोण है, इसलिए +1। एकमात्र मामूली नुकसान यह है कि यदि आपके पास 3 कार्यक्रम हैं, तो आप 3 अलग-अलग आर्ग लेते हुए 3 रैपर स्क्रिप्ट या एक रैपर स्क्रिप्ट हो सकते हैं, जो इसे थकाऊ बना सकता है। फिर भी यह एक ठोस दृष्टिकोण है।
सर्गी कोलोडियाज़नी

1

यहाँ मेरे 2 सेंट है। बस इसे अपने में जोड़ें .bashrcterminalsअपने पसंदीदा टर्मिनलों के साथ बदलें और अपने साथ exportआज्ञा दें।

run_in_terminal(){
  local parent_command="$(ps --no-headers --pid $PPID -o command | awk '{print $1;}')"
  local parent="$(basename $parent_command)"
  local terminals=( gnome-terminal st xterm ) # list your favorite terminal here
  if [[ ${terminals[*]} =~ ${parent} ]]; then
    # Your commands to run if in terminal
    export MY_VAR_IN_TERMINAL="test"
  fi
}
run_in_terminal

यह गनोम-टर्मिनल के सर्वर-क्लाइंट मॉडल के साथ काम नहीं करेगा।
इग्मोंट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.