मैं जिस वर्तमान शेल पर काम कर रहा हूं, उसका निर्धारण कैसे करें


632

मैं जिस वर्तमान शेल पर काम कर रहा हूं, उसका निर्धारण कैसे कर सकता हूं?

क्या psअकेले कमांड का आउटपुट पर्याप्त होगा?

यह यूनिक्स के विभिन्न स्वादों में कैसे किया जा सकता है?


9
विशेष क्षमताओं के लिए परीक्षण (जैसे यह !प्रतिस्थापन करता है ?) संभवतः शेल के नाम को खोजने की तुलना में अधिक पोर्टेबल है। स्थानीय रिवाज हो सकता है कि आप कुछ नाम /bin/shरख लें, जो वास्तव में राख, पानी का छींटा, बैश आदि हो सकता है
msw

1
@msw: एक अच्छी टिप्पणी की तरह लगता है सिवाय इसके कि मुझे "कैसे?" आश्चर्य होता है।
नोबार

ऐसा प्रतीत होता है कि इस प्रश्न का कोई सरल उत्तर नहीं है। यदि हम शेल को क्वेरी नहीं कर सकते हैं , तो शायद बेहतर तरीका हमेशा शेल को निर्दिष्ट करना है। मुझे यकीन नहीं है कि यह हमेशा संभव है, लेकिन शायद यह लोगों को आमतौर पर ग्रहण करने की तुलना में अधिक आसानी से पूरा होता है।
नोबार

इससे मदद मिल सकती है -> Openourceforgeeks.blogspot.in/2013/05/…
अनिकेत ठाकुर

@ अॅनीकेट, इतनी मदद नहीं जितनी आप सोच सकते हैं - यह केवल इंटरेक्टिव शेल प्रक्रियाओं में रुचि रखता है।
टॉबी स्पीट

जवाबों:


793
  • नाम खोजने के लिए तीन दृष्टिकोण हैंवर्तमान शेल के निष्पादन योग्य का :

    कृपया ध्यान दें कि शेल के निष्पादन योग्य होने पर सभी तीन दृष्टिकोणों को मूर्ख बनाया जा सकता है /bin/sh, लेकिन यह वास्तव में एक नया नाम हैbash , उदाहरण के लिए (जो अक्सर होता है)।

    इस प्रकार आपका दूसरा सवाल यह है कि क्या psआउटपुट " हमेशा नहीं " के साथ उत्तर दिया जाएगा ।

    1. echo $0 - प्रोग्राम का नाम प्रिंट करेगा ... जो कि शेल के मामले में वास्तविक शेल है।

    2. ps -ef | grep $$ | grep -v grep- यह चल रही प्रक्रियाओं की सूची में वर्तमान प्रक्रिया आईडी के लिए दिखेगा। चूंकि वर्तमान प्रक्रिया शेल है, इसलिए इसे शामिल किया जाएगा।

      यह 100% विश्वसनीय नहीं है, क्योंकि आपके पास अन्य प्रक्रियाएं हो सकती हैं जिनकी psसूची में शेल की प्रक्रिया आईडी के समान संख्या शामिल है, खासकर यदि वह आईडी एक छोटी संख्या है (उदाहरण के लिए, यदि शेल की पीआईडी ​​"5" है, तो आप प्रक्रियाएं कह सकते हैं। एक ही grepआउटपुट में "java5" या "perl5" ! शेल नाम पर भरोसा करने में सक्षम नहीं होने के शीर्ष पर "पीएस" दृष्टिकोण के साथ यह दूसरी समस्या है।

    3. echo $SHELL- वर्तमान शेल का पथ SHELLकिसी भी शेल के लिए चर के रूप में संग्रहीत किया जाता है । इस के लिए चेतावनी यह है कि यदि आप एक शेल को स्पष्ट रूप से एक उपप्रकार के रूप में लॉन्च करते हैं (उदाहरण के लिए, यह आपका लॉगिन शेल नहीं है), तो आपको इसके बजाय अपने लॉगिन शेल का मान मिलेगा। यदि यह एक संभावना है, psया $0दृष्टिकोण का उपयोग करें ।


  • यदि, हालांकि, निष्पादन योग्य आपके वास्तविक शेल से मेल नहीं खाता (जैसे /bin/shकि वास्तव में बैश या ksh है), तो आपको हेयुरिस्टिक्स की आवश्यकता है। यहाँ विभिन्न गोले के लिए विशिष्ट कुछ पर्यावरणीय चर दिए गए हैं:

    • $version tcsh पर सेट किया गया है

    • $BASH बैश पर सेट है

    • $shell (लोअरकेस) को csh या tsh में वास्तविक शेल नाम पर सेट किया जाता है

    • $ZSH_NAME zsh पर सेट है

    • ksh के पास $PS3और $PS4सेट है, जबकि सामान्य बॉर्न शेल ( sh) में केवल $PS1और $PS2सेट है। यह आम तौर पर की तरह लगता है सबसे मुश्किल भेद करने के लिए - केवल के बीच वातावरण चर के पूरे सेट में अंतर shऔर kshहम सोलारिस बंध पर स्थापित किया है $ERRNO, $FCEDIT, $LINENO, $PPID, $PS3, $PS4, $RANDOM, $SECONDS, और $TMOUT


$ {। sh.version} को ksh93 पर सेट किया गया है
fpmurphy

14
ps -p $$जैसा कि मैथ्यू स्लिटिक बताते हैं। के लिए ksh: echo $KSH_VERSIONया echo ${.sh.version}
अगली सूचना तक रोक दिया गया।

@ अब - मेरे ksh में अभी KSH_VERSION सेट नहीं है। और echo ${.sh.version}"खराब प्रतिस्थापन" लौटाता है। ऊपर मेरा समाधान देखें
DVK

3
" ps -ef | grep …... यह 100% के रूप में विश्वसनीय नहीं है ..." के माध्यम से एक सरल नियमित अभिव्यक्ति का उपयोग करना egrepया grep -eआसानी से सभी-इरादों और उद्देश्यों के लिए 100% तक विश्वसनीयता ला सकता है ps -ef | egrep "^\s*\d+\s+$$\s+":। ^बनाता है यकीन है कि हम लाइन की शुरुआत से शुरू कर रहे हैं, \d+यूआईडी को खाती है, $$पीआईडी से मेल खाता है, और \s*और \s+खाते के लिए और अन्य भागों के बीच खाली स्थान के करता है।
स्लिप डी। थॉम्पसन

2
@ SlippD.Thompson GNU / Linux में काम नहीं किया। लेकिन यह काम करने लगता है:ps -ef | awk '$2==pid' pid=$$
jarno

98

ps -p $$

कहीं भी काम करना चाहिए जिसमें शामिल समाधान ps -efऔर grepकरते हैं (किसी भी यूनिक्स संस्करण पर जो पोसिक्स विकल्पोंps का समर्थन करता है ) और अंकों के अनुक्रम के लिए grepping द्वारा प्रस्तुत झूठी सकारात्मकता से ग्रस्त नहीं होंगे जो कहीं और दिखाई दे सकते हैं।


12
कुछ गोले के अपने स्वयं के निर्मित संस्करण होते हैं, psजो -pआपको समझ में नहीं आ सकते हैं इसलिए आपको उपयोग करने की आवश्यकता हो सकती है /bin/ps -p $$
अगली सूचना तक रोक दिया गया।

12
सभी गोले मुझे समझ से परिचित हूँ $$, सिवाय के लिए fishजिसके साथ आप उपयोग करने के लिए होगा ps -p %self
अगली सूचना तक रोक दिया गया।

3
वास्तव में, आपको इस तरह के एक कठिन रास्तों पर भरोसा नहीं करना चाहिए /bin/pspsआसानी से (वास्तव में यह आजकल काफी सामान्य है) में स्थापित किया जा सकता है /usr/bin$(which ps) -p $$एक बेहतर तरीका है। बेशक, यह मछली में काम नहीं करेगा, और संभवतः कुछ अन्य गोले। मुझे लगता है कि यह (which ps) -p %selfमछली में है।
एरोन सीडरहोम

1
डेबियन-स्लिम डॉकटर कंटेनर जैसी कुछ न्यूनतम प्रणालियों में, पीएस नहीं हो सकता है। उस स्थिति में यह दृष्टिकोण अभी भी काम करता है:readlink /proc/$$/exe
mxmlnkn

अगर आपके shद्वारा अनुकरण किया जाता है bash, तो ps -p आपको /usr/bin/bashयहां तक ​​कि आप इसे चलाते हैंsh
डिंग-यी चेन

45

प्रयत्न

ps -p $$ -oargs=

या

ps -p $$ -ocomm=

4
यह एक अच्छा लघु है। मैं खुद का इस्तेमाल कर रहा था ps -o fname --no-headers $$
ऐनी वैन रोसुम

धन्यवाद। मुझे यह एक स्क्रिप्ट में उपयोग करने के लिए सबसे अच्छा विकल्प मिला जो विशिष्ट कमांड्स को बैश करने के लिए test `ps -p $$ -ocomm=` == "bash" && do_something_that_only_works_in_bash। (मेरी लिपि में अगली पंक्ति csh के बराबर है।)
क्रिक

1
मैंने पाया है कि यदि आप इसे एक उपधारा के भीतर से करते हैं तो यह माता-पिता की PID के साथ-साथ वास्तविक शेल प्रक्रिया से मेल खाते हुए अतिरिक्त रेखाएँ पैदा कर सकता है। इसके लिए, मैं -qइसके बजाय का उपयोग करता हूं -p:SHELL=$(ps -ocomm= -q $$)
स्टीव

35

यदि आप केवल यह सुनिश्चित करना चाहते हैं कि उपयोगकर्ता बैश के साथ एक स्क्रिप्ट का उपयोग कर रहा है:

if [ ! -n "$BASH" ] ;then echo Please run this script $0 with bash; exit 1; fi

1
यह शीर्ष के करीब होना चाहिए। बहुत बहुत धन्यवाद।
एलेक्स स्क्रीपनीक

4
यह शीर्ष के करीब नहीं होना चाहिए, क्योंकि यह सवाल का जवाब नहीं देता है। यदि प्रश्न "कैसे जांच करना है कि क्या स्क्रिप्ट बैश के तहत चल रही है", तो मैं इसके लिए वोट करता हूं।
डेविड फेरेंस्की रोगोजान

2
@DawidFerenczy - जब आप उस वाक्यांश को खोजते हैं तो यह प्रश्न शीर्ष परिणाम होता है। लंबे समय में, मुझे लगता है कि यह बहुत अधिक महत्वपूर्ण है कि उत्तर उस उत्तर की तलाश में है जो लोग मूल प्रश्न के बारे में उत्तर के बजाय क्या देख रहे हैं।
आर्टऑफवर्फ

3
इसके अलावा, चर $ BASH को
tsh के

यह बहुत उपयोगी है, धन्यवाद। बस यह थोड़ा अनुकूलित, के बाद दूसरी पंक्ति के रूप में इस डाल #!/bin/bash: if [ ! -n "$BASH" ] ;then exec bash $0; fi। इस लाइन के साथ स्क्रिप्ट को bash का उपयोग करके चलाया जाता है, भले ही ksh या sh का उपयोग शुरू किया गया हो। मेरे उपयोग के मामले में कमांड लाइन तर्क की आवश्यकता नहीं है, लेकिन $0यदि आवश्यक हो तो उन्हें जोड़ा जा सकता है।
जोनीस

20

तुम कोशिश कर सकते हो:

ps | grep `echo $$` | awk '{ print $4 }'

या:

echo $SHELL

6
जागने के बाद grep की क्या बात है, कब /pattern/ { action }करेंगे?
जेन्स

# zshell उर्फ ​​शेल में = 'गूंज $ {SHELL: t}'
सर्जियोआराज़ो

4
$SHELLपर्यावरण चर में एक शेल होता है, जिसे वर्तमान उपयोगकर्ता के लिए डिफ़ॉल्ट रूप से कॉन्फ़िगर किया गया है। यह एक शेल को प्रतिबिंबित नहीं करता है, जो वर्तमान में चल रहा है। ps -p $$झूठी सकारात्मकता के कारण $ $ का उपयोग करना बेहतर है ।
डेविड फेरेंस्की रोगोजान

$ शेल एन.वी. चर अंक 'अभिभावक' शेल को इंगित करता है, जैसा कि POSIX कल्पना में निर्दिष्ट है: SHELL यह चर उपयोगकर्ता के पसंदीदा कमांड भाषा दुभाषिया के एक मार्गनाम का प्रतिनिधित्व करेगा। इसलिए $ शेल का मूल्य वर्तमान शेल नहीं हो सकता है।
थियो

सभी के भीतर awk,ps | awk '$1=='$$' { n=split($4,a,"/"); print a[n] }'
go2null

16

$SHELLहमेशा वर्तमान शेल दिखाने की आवश्यकता नहीं है। यह केवल डिफ़ॉल्ट शेल को लागू करने के लिए दर्शाता है।

उपरोक्त परीक्षण करने के लिए, मान लेंbash कि डिफ़ॉल्ट शेल है, कोशिश करें echo $SHELL, और फिर उसी टर्मिनल में, उदाहरण के लिए कुछ अन्य शेल ( KornShell (ksh)) में जाएं और प्रयास करें $SHELL। आप परिणाम को दोनों मामलों में बैश के रूप में देखेंगे।

वर्तमान शेल का नाम पाने के लिए, का उपयोग करें cat /proc/$$/cmdline। और शेल द्वारा निष्पादन योग्य पथ readlink /proc/$$/exe


8
... बशर्ते आपके पास हो /proc
ट्रिपल

10

पीएस सबसे विश्वसनीय तरीका है। शेल पर्यावरण चर सेट होने की गारंटी नहीं है और यहां तक ​​कि अगर यह है, तो यह आसानी से खराब हो सकता है।


12
+1 $ SHELL उन कार्यक्रमों के लिए डिफ़ॉल्ट शेल है जिन्हें स्पॉन करने की आवश्यकता है। यह जरूरी नहीं कि जो शेल वर्तमान में चल रहा है, उसे प्रतिबिंबित करें।
जिम लुईस

8

वर्तमान शेल को खोजने के लिए मेरे पास एक सरल चाल है। बस एक यादृच्छिक स्ट्रिंग टाइप करें (जो एक कमांड नहीं है)। यह विफल हो जाएगा और "नहीं मिली" त्रुटि लौटाएगा, लेकिन लाइन के प्रारंभ में यह कहेगा कि यह कौन सा शेल है:

ksh: aaaaa: not found [No such file or directory]
bash: aaaaa: command not found

3
एक स्क्रिप्ट में अच्छा नहीं। echo 'aaaa' > script; chmod +x script; ./scriptदेता है./script.sh: 1: aaaa: not found
स्लिम

6

निम्नलिखित हमेशा उपयोग किए जाने वाले वास्तविक शेल को देगा - इसे वास्तविक निष्पादन योग्य का नाम मिलता है, न कि शेल नाम (अर्थात , आदि के ksh93बजाय ksh)। के लिए /bin/sh, यह वास्तविक शेल का उपयोग करेगा, अर्थात dash

ls -l /proc/$$/exe | sed 's%.*/%%'

मुझे पता है कि कई ऐसे हैं जो कहते हैं कि lsआउटपुट को कभी संसाधित नहीं किया जाना चाहिए, लेकिन आपके द्वारा उपयोग किए जा रहे शेल में क्या संभावना है कि इसे विशेष वर्णों के साथ नाम दिया गया है या विशेष वर्णों के साथ नामित निर्देशिका में रखा गया है? यदि यह अभी भी है, तो इसे अलग तरीके से करने के कई अन्य उदाहरण हैं।

जैसा कि टोबी स्पाइट द्वारा बताया गया है , यह उसी को प्राप्त करने का एक अधिक उचित और क्लीनर तरीका होगा:

basename $(readlink /proc/$$/exe)

3
यह केवल उन सभी यूनियनों पर त्रुटी है जो प्रदान नहीं करते हैं /proc। दुनिया के सभी लिनक्स बॉक्स नहीं।
जेन्स

5
और अगर आप लिनक्स पर हैं , तो हम + + basename $(readlink /proc/$$/exe)को प्राथमिकता देंगे । lssedecho
टोबी स्पाइट

1
यह वास्तविक निष्पादन योग्य का नाम देगा , वास्तविक शेल नहीं । जब वास्तविक शेल को एक व्यस्त बॉक्स एप्लेट के रूप में जोड़ा जाता है, तो कहें ash -> /bin/busybox, यह / बिन / व्यस्त बॉक्स देगा।
चरण

6

मैंने कई अलग-अलग तरीकों की कोशिश की है और मेरे लिए सबसे अच्छा है:

ps -p $$

यह साइगविन के तहत भी काम करता है और पीआईडी ​​ग्रेपिंग के रूप में झूठी सकारात्मकता उत्पन्न नहीं कर सकता है। कुछ सफाई के साथ, यह सिर्फ एक निष्पादन योग्य नाम (पथ के साथ Cygwin के तहत) आउटपुट करता है:

ps -p $$ | tail -1 | awk '{print $NF}'

आप एक समारोह बना सकते हैं ताकि आपको इसे याद रखने की आवश्यकता न हो:

# Print currently active shell
shell () {
  ps -p $$ | tail -1 | awk '{print $NF}'
}

... और फिर अमल करें shell

यह डेबियन और साइगविन के तहत परीक्षण किया गया था।


मेरे सेटअप के रूप में (Cygwin | Windows 7) आपका उत्तर सबसे अच्छा है, और ps -p $$ | पूंछ -1 | gawk '{$ $ NF}' cmd से भी $ bash के बिना काम करता है। कृपया ध्यान दें कि awk के बजाय gawk होता है, क्योंकि awk केवल bash से काम करता है।
वेबकॉम

@WebComer क्षमा करें, मुझे यकीन नहीं है कि आपके द्वारा " $ bash के बिना cmd से भी काम करता है" क्या मतलब है । यहां तक ​​कि अगर आपके पास विंडोज पोर्ट होंगे ps, tailऔर gawk, cmd परिभाषित नहीं करता है $$क्योंकि यह PID है तो यह निश्चित रूप से सादे cmd के तहत काम नहीं कर सकता है।
डेविड फेरेंस्की रोगोज़न

बस क्यों नहीं ps -p$$ -o comm=? POSIX का कहना है कि सभी हेडर को निर्दिष्ट करने से हेडर पूरी तरह से दब जाता है। psजब हम एक सीधे निष्पादित स्क्रिप्ट (जैसे #!/bin/sh) द्वारा सॉर्ट किए जाते हैं तब भी हम (सभी उत्तरों की तरह ) विफल हो रहे हैं ।
टॉबी स्पाइट

5

मूल प्रक्रिया को मुद्रित करने पर मेरा प्रकार:

ps -p $$ | awk '$1 == PP {print $4}' PP=$$

जब AWK आपके लिए यह कर सकता है तो अनावश्यक एप्लिकेशन न चलाएं।


2
एक अनावश्यक क्यों चलाएं awk, ps -p "$$" -o 'comm='यह आपके लिए कब हो सकता है?
टोबे स्पीट

5

शेल और इसके संबंधित संस्करण का पता लगाने के कई तरीके हैं। यहाँ कुछ हैं जो मेरे लिए काम किया है।

सरल

  1. $> इको $ 0 (आपको कार्यक्रम का नाम देता है। मेरे मामले में आउटपुट -bash था ।)
  2. $> $ SHELL (यह आपको शेल में ले जाता है और प्रॉम्प्ट में आपको शेल नाम और संस्करण मिलता है। मेरे मामले में b3.3.2 $ )
  3. $> इको $ शेल (यह आपको निष्पादन योग्य मार्ग देगा। मेरे मामले में / बिन / बैश ।)
  4. $> $ शेल - विसर्जन (यह लाइसेंस प्रकार के साथ शेल सॉफ्टवेयर के बारे में पूरी जानकारी देगा)

Hackish दृष्टिकोण

$> ******* (यादृच्छिक अक्षरों का एक सेट टाइप करें और आउटपुट में आपको शेल नाम मिलेगा। मेरे मामले में -बेश: Chapter2-a-sample-isomorphic-app: कमांड नहीं मिला )


3

बशर्ते कि आपका /bin/shPOSIX मानक का समर्थन करता है और आपके सिस्टम में lsofकमांड स्थापित है - lsofइस मामले में हो सकने वाला एक संभावित विकल्प pid2path- आप निम्न स्क्रिप्ट का उपयोग (या अनुकूलन) कर सकते हैं जो पूर्ण पथ प्रिंट करता है:

#!/bin/sh
# cat /usr/local/bin/cursh
set -eu
pid="$$"

set -- sh bash zsh ksh ash dash csh tcsh pdksh mksh fish psh rc scsh bournesh wish Wish login

unset echo env sed ps lsof awk getconf

# getconf _POSIX_VERSION  # reliable test for availability of POSIX system?
PATH="`PATH=/usr/bin:/bin:/usr/sbin:/sbin getconf PATH`"
[ $? -ne 0 ] && { echo "'getconf PATH' failed"; exit 1; }
export PATH

cmd="lsof"
env -i PATH="${PATH}" type "$cmd" 1>/dev/null 2>&1 || { echo "$cmd not found"; exit 1; }

awkstr="`echo "$@" | sed 's/\([^ ]\{1,\}\)/|\/\1/g; s/ /$/g' | sed 's/^|//; s/$/$/'`"

ppid="`env -i PATH="${PATH}" ps -p $pid -o ppid=`"
[ "${ppid}"X = ""X ] && { echo "no ppid found"; exit 1; }

lsofstr="`lsof -p $ppid`" || 
   { printf "%s\n" "lsof failed" "try: sudo lsof -p \`ps -p \$\$ -o ppid=\`"; exit 1; }

printf "%s\n" "${lsofstr}" | 
   LC_ALL=C awk -v var="${awkstr}" '$NF ~ var {print $NF}'

1
यह मछली में काम करता है! लेकिन मेरे लिए, बैश में विफल रहता है, -i(-> पर्यावरण को अनदेखा) विकल्प के envकारण लाइन में जहाँ आप lsofउपलब्ध होने के लिए जाँच करते हैं। यह विफल रहता है: env -i PATH="${PATH}" type lsof->env: ‘type’: No such file or directory
hoijui

2

यदि आप बस यह जांचना चाहते हैं कि आप (बैश का एक विशेष संस्करण) चला रहे हैं, तो ऐसा करने का सबसे अच्छा तरीका $BASH_VERSINFOसरणी चर का उपयोग करना है। एक (केवल पढ़ने के लिए) सरणी चर के रूप में इसे पर्यावरण में सेट नहीं किया जा सकता है, इसलिए आप यह सुनिश्चित कर सकते हैं कि यह (यदि सभी में) चालू शेल से आ रहा है।

हालाँकि, जब बैश को एक अलग व्यवहार किया जाता है sh, जैसा कि आपको बताया जाता है , तो आपको $BASHपर्यावरण के चर के साथ समाप्त होने की भी जाँच करने की आवश्यकता है /bash

एक स्क्रिप्ट में मैंने लिखा था कि -अंडरस्कोर (नहीं अंडरस्कोर) के साथ फ़ंक्शन नामों का उपयोग करता है , और साहचर्य सरणियों पर निर्भर करता है (बैश 4 में जोड़ा गया), मेरे पास निम्नलिखित सैनिटरी चेक (सहायक उपयोगकर्ता त्रुटि संदेश के साथ) है:

case `eval 'echo $BASH@${BASH_VERSINFO[0]}' 2>/dev/null` in
    */bash@[456789])
        # Claims bash version 4+, check for func-names and associative arrays
        if ! eval "declare -A _ARRAY && func-name() { :; }" 2>/dev/null; then
            echo >&2 "bash $BASH_VERSION is not supported (not really bash?)"
            exit 1
        fi
        ;;
    */bash@[123])
        echo >&2 "bash $BASH_VERSION is not supported (version 4+ required)"
        exit 1
        ;;
    *)
        echo >&2 "This script requires BASH (version 4+) - not regular sh"
        echo >&2 "Re-run as \"bash $CMD\" for proper operation"
        exit 1
        ;;
esac

आप पहले मामले में सुविधाओं के लिए कुछ हद तक पागल कार्यात्मक जांच को छोड़ सकते हैं, और बस यह मान लें कि भविष्य के बैश संस्करण संगत होंगे।


2

कोई भी उत्तर fishशेल के साथ काम नहीं करता है (इसमें चर नहीं हैं $$या $0)।

मेरे लिए यह काम करता है (पर परीक्षण किया sh, bash, fish, ksh, csh, true, tcsh, और zsh, openSUSE 13.2):

ps | tail -n 4 | sed -E '2,$d;s/.* (.*)/\1/'

यह कमांड एक स्ट्रिंग को आउटपुट करता है जैसे bash। यहाँ मैं केवल उपयोग कर रहा हूँ ps, tailऔर sed(जीएनयू extesions के बिना, जोड़ने की कोशिश --posixयह जाँच करने के लिए)। वे सभी मानक POSIX कमांड हैं। मुझे यकीन है कि tailहटाया जा सकता है, लेकिन sedऐसा करने के लिए मेरा फू इतना मजबूत नहीं है।

यह मुझे लगता है, कि यह समाधान बहुत पोर्टेबल नहीं है क्योंकि यह ओएस एक्स पर काम नहीं करता है। :(


मैं sed: invalid option -- 'E'बैश 3.2.51 और tcsh 6.15.00
सनक

2

मेरा समाधान:

ps -o command | grep -v -e "\<ps\>" -e grep -e tail | tail -1

यह विभिन्न प्लेटफार्मों और गोले में पोर्टेबल होना चाहिए। यह psअन्य समाधानों की तरह उपयोग करता है , लेकिन यह निर्भर नहीं करता है sedया awkपाइपिंग से जंक को फ़िल्टर करता है और psखुद को खोल देता है ताकि शेल हमेशा अंतिम प्रविष्टि हो। इस तरह हमें गैर-पोर्टेबल पीआईडी ​​वैरिएबल पर निर्भर होने या सही लाइनों और कॉलम को चुनने की आवश्यकता नहीं है।

मैंने बैश, जेड शेल ( zsh) के साथ डेबियन और मैकओएस पर परीक्षण किया है , और मछली (जो विशेष रूप से मछली के लिए अभिव्यक्ति को बदलने के बिना इनमें से अधिकांश समाधानों के साथ काम नहीं करता है, क्योंकि यह एक अलग पीआईडी ​​चर का उपयोग करता है)।


1
echo $$ # Gives the Parent Process ID 
ps -ef | grep $$ | awk '{print $8}' # Use the PID to see what the process is.

से तुम कैसे जानते हो क्या अपने वर्तमान खोल रहा है?


3
यह मूल प्रक्रिया नहीं है - यह वर्तमान प्रक्रिया है।
अगली सूचना तक रोक दिया गया।

7
उपयोग करना grep $$अविश्वसनीय है। ps -ef | awk -v pid=$$ '$2==pid { print $8 }'बेहतर है, लेकिन सिर्फ उपयोग क्यों नहीं ps -p $$?
मुशीफिल

1

Mac OS X (और FreeBSD) पर:

ps -p $$ -axco command | sed -n '$p' 

2
उपयोग करते समय यह कोशिश की zsh, और यह मुझे दिया -bash
user137369

मेरे सिस्टम (अब) पर, बैश और डैश के साथ परीक्षण किया गया, यह वापसी mutt...: -बी
एफ। होरी

1

"पीएस" के आउटपुट से ग्रेपिंग पीआईडी ​​की आवश्यकता नहीं है, क्योंकि आप / खरीद संरचना से किसी भी पीआईडी ​​के लिए संबंधित कमांड लाइन पढ़ सकते हैं:

echo $(cat /proc/$$/cmdline)

हालाँकि, यह किसी भी तरह से बेहतर नहीं हो सकता है:

echo $0

नाम की तुलना में वास्तव में एक अलग शेल चलाने के बारे में, एक विचार यह है कि आपको पहले प्राप्त नाम का उपयोग करके शेल से संस्करण का अनुरोध करना है:

<some_shell> --version

sh बाहर निकलने के कोड 2 के साथ विफल होने के लिए लगता है जबकि अन्य कुछ उपयोगी देते हैं (लेकिन मैं सभी को सत्यापित करने में सक्षम नहीं हूं क्योंकि मेरे पास नहीं है):

$ sh --version
sh: 0: Illegal option --
echo $?
2

1

यह बहुत साफ समाधान नहीं है, लेकिन यह वही करता है जो आप चाहते हैं।

# MUST BE SOURCED..
getshell() {
    local shell="`ps -p $$ | tail -1 | awk '{print $4}'`"

    shells_array=(
    # It is important that the shells are listed in descending order of their name length.
        pdksh
        bash dash mksh
        zsh ksh
        sh
    )

    local suited=false
    for i in ${shells_array[*]}; do
        if ! [ -z `printf $shell | grep $i` ] && ! $suited; then
            shell=$i
            suited=true
        fi
    done

    echo $shell
}
getshell

अब आप उपयोग कर सकते हैं $(getshell) --version

यह काम करता है, हालांकि, केवल कोर्नशेल -जैसे गोले (ksh) पर।


1
"यह काम करता है, हालांकि, केवल ksh- जैसे गोले पर।" क्या आप कह रहे हैं कि मुझे इसे चलाने से पहले शेल को सत्यापित करना होगा? हम्म ...
jpaugh

@jpaugh, सूचियों खोल इस कोड सोर्सिंग, जिसके लिए मामला नहीं है द्वारा समर्थित होना चाहिए dash, yashआदि आम तौर पर अगर आप उपयोग कर रहे हैं bash, zsh, ksh, जो कुछ भी - आप इस तरह की चीजों के बारे में परवाह नहीं करनी चाहिए।
थियोडेन 8

तो आप "ksh-like" के रूप में बैश गिन रहे हैं? समझ गया। यह अधिक समझ में आता है
jpaugh

@jpaugh, ठीक है, कि मैं क्या मतलब है क्योंकि kshसुविधाओं का एक सेट ज्यादातर सुविधाओं का एक सबसेट bashहै (यह पूरी तरह से जाँच नहीं की है)।
थियोडेन 8

1

यह जानने के लिए कि क्या आपका शेल डैश / बैश का उपयोग कर रहा है, निम्नलिखित करें।

ls –la /bin/sh:

  • यदि परिणाम /bin/sh -> /bin/bash==> है तो आपका शेल बैश का उपयोग कर रहा है।

  • यदि परिणाम /bin/sh ->/bin/dash==> तो आपका शेल डैश का उपयोग कर रहा है।

यदि आप बैश से डैश या इसके विपरीत बदलना चाहते हैं, तो नीचे दिए गए कोड का उपयोग करें:

ln -s /bin/bash /bin/sh (बैश को शेल बदलें)

नोट : यदि उपरोक्त कमांड में यह कहते हुए त्रुटि है, कि / bin / sh पहले से मौजूद है, / bin / sh को हटा दें और पुनः प्रयास करें।


0

और मैं इस के साथ आया था

sed 's/.*SHELL=//; s/[[:upper:]].*//' /proc/$$/environ

यह केवल लिनक्स पर काम करेगा ! न MacOS, न ही BSD !!
एफ। हौरी

-1

कृपया नीचे दिए गए आदेश का उपयोग करें:

ps -p $$ | tail -1 | awk '{print $4}'

पहले एक बकवास है, echo $SHELLवह करता है जो आप करने की कोशिश कर रहे हैं और इसे अच्छी तरह से करते हैं। दूसरा भी अच्छा नहीं है, क्योंकि $SHELLपर्यावरण चर में वर्तमान उपयोगकर्ता के लिए डिफ़ॉल्ट शेल होता है, वर्तमान में चल रहे शेल में नहीं। अगर मुझे उदाहरण के लिए bashडिफ़ॉल्ट शेल के रूप में सेट करना है, तो निष्पादित करें zshऔर echo $SHELL, इसे प्रिंट करेंगे bash
डेविड फेरेंस्की रोगोजान

आप दाविद फेरेंज़ी सही हैं, हम वर्तमान शेल को निर्धारित करने के लिए पीएस कमांड का उपयोग कर सकते हैं। [# ps -p $ $ | पूंछ -1 | awk '{प्रिंट $ 4}']।
रंजीथकुमार टी

echo $SHELLबकवास हो सकता है: ~ $ echo $SHELL /bin/zsh ~ $ bash bash-4.3$ echo $SHELL /bin/zsh bash-4.3$
साल्टवॉटर

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