বর্তমান শেলটি কীভাবে নির্ধারণ করব আমি কাজ করছি


632

আমি যে বর্তমান শেলটি নিয়ে কাজ করছি তা কীভাবে নির্ধারণ করতে পারি?

psকমান্ডের আউটপুট একা যথেষ্ট হবে?

এটি কীভাবে ইউনিক্সের বিভিন্ন স্বাদে করা যেতে পারে?


9
নির্দিষ্ট দক্ষতার জন্য পরীক্ষা করা (উদাহরণস্বরূপ এটি কী !বিকল্প ব্যবহার করে?) শেলের নাম খুঁজে পাওয়ার চেয়ে সম্ভবত বেশি বহনযোগ্য। স্থানীয় রীতিনীতিতে আপনার এমন কিছু চালানো হতে পারে /bin/shযা আসলে ছাই, ড্যাশ, বাশ ইত্যাদি হতে পারে
এমএসডাব্লু

1
@ এমএসডব্লিউ: এটি "কীভাবে?" ভাবছেন তা বাদ দিয়ে একটি ভাল মন্তব্য বলে মনে হচ্ছে।
নোটার

দেখা যাচ্ছে যে এই প্রশ্নের কোনও সহজ উত্তর নেই। আমরা না পারেন, তাহলে প্রশ্ন শেল, হয়তো ভাল পদ্ধতির সবসময় হয় উল্লেখ শেল। আমি নিশ্চিত নই যে এটি সর্বদা সম্ভব, তবে লোকেরা সাধারণত ধারণা করা থেকে এটি সহজেই সম্পন্ন হয়।
নোটার

এটি সহায়তা করতে পারে -> opensourceforgeeks.blogspot.in/2013/05/…
অনিকেত ঠাকুর

অ্যানিকেট, আপনার মনে হতে পারে তেমন সহায়তা নয় - এটি কেবল ইন্টারেক্টিভ শেল প্রক্রিয়াতে আগ্রহী ।
টবি স্পিড

উত্তর:


793
  • নামটি খুঁজতে তিনটি পন্থা রয়েছেবর্তমান শেলের এক্সিকিউটেবলের :

    দয়া করে মনে রাখবেন যে শেলটি কার্যকর করার যোগ্য হলে তিনটি পদ্ধতিরই বোকা হতে পারে /bin/shতবে এটি সত্যই একটি নামকরণ হয়েছে bash, উদাহরণস্বরূপ (যা ঘন ঘন ঘটে) happens

    সুতরাং psআউটপুটটি করবে কিনা আপনার দ্বিতীয় প্রশ্নের উত্তর " সর্বদা নয় " দিয়ে দেওয়া হবে।

    1. echo $0 - প্রোগ্রামটির নাম মুদ্রণ করবে ... যা শেলের ক্ষেত্রে প্রকৃত শেল।

    2. ps -ef | grep $$ | grep -v grep- এটি চলমান প্রক্রিয়াগুলির তালিকায় বর্তমান প্রক্রিয়া আইডি সন্ধান করবে। যেহেতু বর্তমান প্রক্রিয়াটি শেল, তাই এটি অন্তর্ভুক্ত করা হবে।

      এটি 100% নির্ভরযোগ্য নয়, কারণ আপনার অন্যান্য প্রসেস থাকতে পারে যার psতালিকায় শেলের প্রসেস আইডির সমান নম্বর রয়েছে, বিশেষত যদি সেই আইডি একটি ছোট সংখ্যা হয় (উদাহরণস্বরূপ, যদি শেলের পিআইডি "5" হয়, তবে আপনি প্রক্রিয়াগুলি পেতে পারেন "java5" বা "পার্ল 5" একই grepআউটপুটে!)। শেল নামের উপর নির্ভর করতে না পারার শীর্ষে, এটি "পিএস" পদ্ধতির সাথে দ্বিতীয় সমস্যা।

    3. echo $SHELL- বর্তমান শেলটির পথটি SHELLকোনও শেলের জন্য পরিবর্তনশীল হিসাবে সংরক্ষণ করা হয় । এটির জন্য সতর্কতা হ'ল আপনি যদি একটি শেলটি উপ-প্রসেস হিসাবে স্পষ্টভাবে চালু করেন (উদাহরণস্বরূপ, এটি আপনার লগইন শেল নয়) তবে আপনি তার পরিবর্তে আপনার লগইন শেলের মান পাবেন। যদি এটির কোনও সম্ভাবনা থাকে তবে ব্যবহার করুন psবা $0পদ্ধতিটি ব্যবহার করুন ।


  • তবে, যদি এক্সিকিউটেবল আপনার আসল শেলের সাথে মেলে না (যেমন /bin/shপ্রকৃতপক্ষে বাশ বা ksh), আপনার হিউরিস্টিক্স দরকার। বিভিন্ন শেলের জন্য নির্দিষ্ট কিছু পরিবেশগত পরিবর্তনগুলি এখানে রয়েছে:

    • $version tcsh এ সেট করা আছে

    • $BASH বাশ সেট করা আছে

    • $shell (ছোট হাতের অক্ষর) csh বা tcsh এ প্রকৃত শেল নেমে সেট করা আছে

    • $ZSH_NAME zsh এ সেট করা আছে

    • ksh আছে $PS3এবং $PS4সেট করেছে, যেখানে সাধারণ বোর্ন শেল ( sh) কেবল থাকে $PS1এবং $PS2সেট করে। সাধারণত মত মনে হয় কঠিন পার্থক্য - শুধুমাত্র মধ্যে এনভায়রনমেন্ট ভেরিয়েবল সমগ্র সেট পার্থক্য shএবং kshআমরা সোলারিস বক্স্-বৃক্ষের কাষ্ঠে নির্মিত ইনস্টল করেছি $ERRNO, $FCEDIT, $LINENO, $PPID, $PS3, $PS4, $RANDOM, $SECONDS, এবং $TMOUT


। sh। sh.version k ksh93
fpmurphy


@ ডেনিশ - আমার কেশিতে এখনই কেএসএইচ_ভার্সন সেট নেই। এবং echo ${.sh.version}"খারাপ সাবস্টিটিউশন" প্রদান করে। আমার সমাধানটি উপরে দেখুন
ডিভিকে

3
" ps -ef | grep …... এই না 100% নির্ভরযোগ্য হিসাবে ... হল" এর মাধ্যমে একটি সহজ রেগুলার এক্সপ্রেশন ব্যবহার egrepবা grep -eসহজেই নির্ভরযোগ্যতা আপ আনতে পারেন জন্য-অল-ইন্টেন্ট-এবং-উদ্দেশ্যের 100%: ps -ef | egrep "^\s*\d+\s+$$\s+"। এটি ^নিশ্চিত করে যে আমরা লাইনের শুরু থেকেই শুরু করছি, \d+ইউআইডি খায়, $$পিআইডি মেলে, এবং অন্যান্য অংশের মধ্যে শ্বেতস্পেসের জন্য অ্যাকাউন্ট \s*এবং \s+অ্যাকাউন্টটি নিশ্চিত করে।
স্লিপ ডি থম্পসন

2
@ স্লিপডি.টমসন জিএনইউ / লিনাক্সে কাজ করেনি। তবে এটি কাজ করছে বলে মনে হচ্ছে:ps -ef | awk '$2==pid' pid=$$
14-18

98

ps -p $$

সমাধানগুলি জড়িত ps -efgrepকরতে পারে এমন যে কোনও জায়গায় কাজ করা উচিত (কোনও ইউনিক্স ভেরিয়েন্টে যা পসিক্স বিকল্পগুলির পক্ষেps সমর্থন করে ) এবং অন্য কোথাও প্রদর্শিত হতে পারে এমন অঙ্কগুলির ক্রম জন্য গ্রেপিংয়ের মাধ্যমে প্রবর্তিত মিথ্যা ইতিবাচকতায় ভুগবে না।


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
সেক্ষেত্রে

যদি আপনার shদ্বারা অনুকরণ করা হয় bash, পিএস-পি আপনাকে /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
আমি খুঁজে পেয়েছি যে আপনি যদি এটি কোনও সাব-শেলের মধ্যে থেকে করেন তবে এটি পিতামাতার পিআইডি এবং প্রকৃত শেল প্রক্রিয়াটির সাথে মিলিয়ে উত্সাহী অতিরিক্ত লাইন তৈরি করতে পারে। এর জন্য, আমি এর -qপরিবর্তে ব্যবহার করব -p:SHELL=$(ps -ocomm= -q $$)
স্টিভ

35

আপনি যদি কেবল নিশ্চিত করতে চান যে ব্যবহারকারী বাশের সাথে একটি স্ক্রিপ্ট চাচ্ছেন:

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

1
এটি শীর্ষে থাকা উচিত one অনেক ধন্যবাদ.
অ্যালেক্স স্ক্রাইপন্যিক

4
এটি শীর্ষের কাছাকাছি হওয়া উচিত নয়, কারণ এটি প্রশ্নের কোনও উত্তর দেয় না। যদি প্রশ্নটি হয় "স্ক্রিপ্টটি বাশের অধীনে চলছে কিনা তা কীভাবে পরীক্ষা করবেন", আমি এটির পক্ষে ভোট দিই।
ডেভিড ফেরেঞ্জি রোগোয়ান

2
@ ডেভিডফেরেঞ্জি - আপনি যদিও এই বাক্যাংশটি অনুসন্ধান করার পরে এই প্রশ্নটি শীর্ষ ফলাফল। দীর্ঘমেয়াদে, আমি মনে করি এটি আরও বেশি গুরুত্বপূর্ণ যে উত্তরগুলি মূল প্রশ্নটি সম্পর্কে জবাব দেওয়ার চেয়ে লোকেরা যা খুঁজছে তার উত্তর দেয়।
আর্টঅফ ওয়ারফেয়ার

3
উপরন্তু, পরিবর্তনশীল $ BASH হয় tcsh শেল অধীনে সংজ্ঞায়িত যদি tcsh শেল ব্যাশ থেকে বরকত হয়
18446744073709551615

এটি খুব দরকারী, আপনাকে ধন্যবাদ। শুধু তা একটু অভিযোজিত পর দ্বিতীয় লাইন হিসাবে এই নির্বাণ #!/bin/bash: if [ ! -n "$BASH" ] ;then exec bash $0; fi। এই লাইনের সাহায্যে স্ক্রিপ্টটি ব্যাশ ব্যবহার করে চালানো হয় এমনকি ksh বা sh ব্যবহার করা শুরু করে। আমার ব্যবহারের ক্ষেত্রে কমান্ড লাইন আর্গুমেন্টের প্রয়োজন নেই, তবে প্রয়োজনে সেগুলি যুক্ত করা যেতে পারে $0
joanis

20

আপনি চেষ্টা করতে পারেন:

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

বা:

echo $SHELL

6
গ্রেপ এর পয়েন্টটি এর পরে কী /pattern/ { action }হবে , কখন করবে?
জেনস

# জেসেল ওরফে শেলের মধ্যে = 'প্রতিধ্বনি {
EL

4
$SHELLএনভায়রনমেন্ট ভেরিয়েবলে একটি শেল রয়েছে, যা বর্তমান ব্যবহারকারীর জন্য ডিফল্ট হিসাবে কনফিগার করা আছে। এটি বর্তমানে চালিত শেলকে প্রতিফলিত করে না। ps -p $$মিথ্যা ধনাত্মকতার কারণে গ্রেপিংয়ের চেয়ে এটি ব্যবহার করা ভাল ।
ডেভিড ফেরেঞ্জি রোগোয়ান

দ্য শেল এনভিউ 'প্যারেন্ট' শেলটিতে ভেরিয়েবল পয়েন্ট, যেমন পসিক্স স্পেসে উল্লেখ করা হয়েছে: শেল এই ভেরিয়েবলটি ব্যবহারকারীর পছন্দের কমান্ড ল্যাঙ্গুয়েজ ইন্টারপ্রেটারের একটি নামের প্রতিনিধিত্ব করবে। সুতরাং $ শেল এর মান বর্তমান শেল নাও হতে পারে।
থিও 4'15

সমস্ত ভিতরে awk,ps | awk '$1=='$$' { n=split($4,a,"/"); print a[n] }'
go2null

16

$SHELLসর্বদা বর্তমান শেলটি দেখানোর দরকার নেই। এটি কেবলমাত্র চাওয়ার জন্য ডিফল্ট শেল প্রতিফলিত করে।

উপরেরটি পরীক্ষা করতে, বলুন bashডিফল্ট শেল, চেষ্টা করুন echo $SHELLএবং তারপরে একই টার্মিনালে অন্য কোনও শেল ( উদাহরণস্বরূপ কর্নশেল (ksh)) এ গিয়ে চেষ্টা করুন $SHELL। উভয় ক্ষেত্রেই আপনি ফলাফলটিকে বাশ হিসাবে দেখবেন।

বর্তমান শেলটির নাম পেতে, ব্যবহার করুন cat /proc/$$/cmdline। এবং খোলার দ্বারা নির্বাহযোগ্য পথ readlink /proc/$$/exe


8
... যদি আপনি পেয়ে থাকেন /proc
ট্রিপলি

10

PS সবচেয়ে নির্ভরযোগ্য পদ্ধতি। শেল পরিবেশের পরিবর্তনশীল সেট হওয়ার নিশ্চয়তা নেই এবং এটি থাকলেও এটি সহজেই ছদ্মবেশী হতে পারে।


12
+1 $ শেল হ'ল এমন প্রোগ্রামগুলির জন্য ডিফল্ট শেল। এটি বর্তমানে চলমান শেলটি অগত্যা প্রতিফলিত করে না।
জিম লুইস

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)করতে ls+ + sed+ + echo
টবি স্পিড

1
এটি প্রকৃত শেল নয়, প্রকৃত এক্সিকিউটেবলের নাম দেবে । যখন আসল শেলটি একটি ব্যস্তবক্স অ্যাপলেট হিসাবে সংযুক্ত থাকে, বলুন , এটি / বিন / ব্যস্তবক্স দেবে। ash -> /bin/busybox
পদক্ষেপ

6

আমি অনেকগুলি ভিন্ন পদ্ধতির চেষ্টা করেছি এবং আমার জন্য সেরাটি হ'ল:

ps -p $$

এছাড়া অধীনে কাজ করে Cygwin এবং PID, grepping মিথ্যা পজিটিভ দিতে পারছে না। কিছু পরিষ্কারের মাধ্যমে, এটি কেবলমাত্র একটি এক্সিকিউটেবল নাম (পথ সহ সিগউইনের অধীনে) আউটপুট দেয়:

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

আপনি একটি ফাংশন তৈরি করতে পারেন যাতে আপনাকে এটি মুখস্ত করতে হবে না:

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

... এবং তারপর চালানো shell

এটি দেবিয়ান এবং সাইগউইনের অধীনে পরীক্ষা করা হয়েছিল।


আমার সেটআপ হিসাবে (সাইগউইন | উইন্ডোজ)) আপনার উত্তরটি সেরা এবং পিএস-পি $$ | লেজ -1 | গাক '{মুদ্রণ $ এনএফ}' এমনকি d বাশ ছাড়াই সেন্টিমিডি থেকে কাজ করে। দয়া করে awk এর পরিবর্তে গাওকটি নোট করুন, যেমন অ্যাশক শুধুমাত্র বাশ থেকে কাজ করে।
ওয়েবকোমর

@ ওয়েবকোমার দুঃখিত, আপনি "cm বাশ এমনকি সিএমডি থেকেও কাজ করে" বলতে চাইছেন তা নিশ্চিত নই । এমনকি যদি আপনার উইন্ডোজ পোর্টগুলি থাকে ps, tailএবং gawk, সিএমডি সংজ্ঞায়িত হয় না$$ এটি পিআইডি হিসাবে যাতে এটি অধীনে কাজ করতে পারে না।
ডেভিড ফেরেঞ্জি রোগোয়ান

কেন সহজভাবে না ps -p$$ -o comm= ? পসিক্স বলে যে সমস্ত শিরোনাম খালি উল্লেখ করা শিরোনামকে পুরোপুরি দমন করে। আমরা সরাসরি ব্যর্থ psহব (সমস্ত উত্তরগুলির মতো) যখন আমরা সরাসরি সম্পাদিত স্ক্রিপ্টের মাধ্যমে উত্সাহিত করি (যেমন #!/bin/sh)।
টবি স্পিড

5

পিতামাতার প্রক্রিয়াটি মুদ্রণের ক্ষেত্রে আমার বৈকল্পিক:

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

যখন এডাব্লুके আপনার পক্ষে এটি করতে পারে তখন অপ্রয়োজনীয় অ্যাপ্লিকেশনগুলি চালাবেন না।


2
অযথা চালাবেন কেন awk, কখন ps -p "$$" -o 'comm='আপনার জন্য এটি করতে পারে?
টবি স্পিড

5

শেল এবং এর সম্পর্কিত সংস্করণটি খুঁজে বের করার অনেকগুলি উপায় রয়েছে। এখানে আমার জন্য কাজ করেছেন এমন কিছু লোক রয়েছে।

অকপট

  1. $> প্রতিধ্বনি $ 0 (আপনাকে প্রোগ্রামের নাম দেয় my আমার ক্ষেত্রে আউটপুটটি ছিল -বাশ )
  2. $> $ শেল (এটি আপনাকে শেলের মধ্যে নিয়ে যায় এবং প্রম্পটে আপনি শেলের নাম এবং সংস্করণ পাবেন my আমার ক্ষেত্রে bash3.2 $ ।)
  3. cho > প্রতিধ্বনি $ শেল (এটি আপনাকে এক্সিকিউটেবল পাথ দেবে bin আমার ক্ষেত্রে / বিন / বাশ ))
  4. $> EL শেল - রূপান্তর (এটি লাইসেন্সের ধরণের শেল সফটওয়্যার সম্পর্কে সম্পূর্ণ তথ্য দেবে)

হ্যাকিশ পদ্ধতির

$> ******* (র্যান্ডম অক্ষর একটি সেট টাইপ করুন এবং আউটপুটে আপনি শেল নাম পাবেন আমার ক্ষেত্রে। -Bash: chapter2-এ-নমুনা-isomorphic-অ্যাপ: COMMAND পাওয়া যায়নি )


3

প্রদত্ত যে আপনার /bin/shপসিক্স স্ট্যান্ডার্ডকে সমর্থন করে এবং আপনার সিস্টেমে 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উপলভ্য হওয়ার জন্য পরীক্ষা করেন to এটি এতে ব্যর্থ: env -i PATH="${PATH}" type lsof->env: ‘type’: No such file or directory
হোইজুই

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

ম্যাক ওএস এক্সে (এবং ফ্রিবিএসডি):

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

2
ব্যবহার করার সময় zshএটি চেষ্টা করেছিলাম এবং এটি আমাকে দিয়েছে -bash
ব্যবহারকারী 137369

আমার সিস্টেমে (এখন) ব্যাশ এবং ড্যাশ দিয়ে পরীক্ষা করা হয়েছে, এই প্রত্যাবর্তন 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যাই হোক না কেন - আপনি এই ধরনের জিনিস যত্নশীল করা উচিত নয়।
theoden8

সুতরাং আপনি বাশকে "ksh- মত" হিসাবে গণনা করছেন? বুঝেছি. এটি আরও
অর্থবোধ করে

@ জেপফো, ভাল, আমি এটাই বোঝাতে চেয়েছিলাম কারণ kshবৈশিষ্ট্যগুলির সেটটি বেশিরভাগ বৈশিষ্ট্যের একটি উপসেট bash(যদিও এটি পুরোপুরি পরীক্ষা করা হয়নি)।
theoden8

1

আপনার শেল ড্যাশ / বাশ ব্যবহার করছে কিনা তা জানতে নিম্নলিখিতগুলি করুন।

ls –la /bin/sh:

  • যদি ফলাফল /bin/sh -> /bin/bash==> থাকে তবে আপনার শেলটি ব্যাশ ব্যবহার করছে।

  • যদি ফলাফল /bin/sh ->/bin/dash==> থাকে তবে আপনার শেলটি ড্যাশ ব্যবহার করছে।

আপনি যদি বাশ থেকে ড্যাশ বা তদ্বিপরীত পরিবর্তন করতে চান তবে নীচের কোডটি ব্যবহার করুন:

ln -s /bin/bash /bin/sh (বাশে শেল পরিবর্তন করুন)

দ্রষ্টব্য : উপরের কমান্ডটি যদি ত্রুটিতে ফলাফল করে / / বিন / শ ইতিমধ্যে উপস্থিত থাকে তবে / বিন / শ সরিয়ে আবার চেষ্টা করুন।


0

এবং আমি এটি নিয়ে এসেছি

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

এটি কেবল লিনাক্সে কাজ করবে ! ম্যাকোএস নয়, বিএসডিও নয় !!
এফ। হাউরি 13

-1

দয়া করে নীচের কমান্ডটি ব্যবহার করুন:

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

প্রথমটি হ'ল আজেবাজে কথা, echo $SHELLআপনি যা করার চেষ্টা করছেন তা করে এবং এটি ভাল করে। দ্বিতীয়টিও ভাল নয়, কারণ $SHELLপরিবেশের ভেরিয়েবলটিতে বর্তমান ব্যবহারকারীর জন্য ডিফল্ট শেল রয়েছে, বর্তমানে চলমান শেল নয়। যদি আমার উদাহরণস্বরূপ bashডিফল্ট শেল হিসাবে সেট থাকে তবে এক্সিকিউট করুন zshএবং echo $SHELLএটি মুদ্রণ করবে bash
ডেভিড ফেরেঞ্জি রোগোয়ান

আপনি সঠিক দাউদ ফেরেঞ্জি, আমরা বর্তমান শেল নির্ধারণ করতে PS কমান্ড ব্যবহার করতে পারি। [# পিএস -পি $$ | লেজ -1 | awk '{মুদ্রণ $ 4}']।
রঞ্জিতকুমার টি

echo $SHELLআবর্জনা হতে পারে: ~ $ echo $SHELL /bin/zsh ~ $ bash bash-4.3$ echo $SHELL /bin/zsh bash-4.3$
সল্টওয়াটারসি

-2

এটি রেড হ্যাট লিনাক্স ( আরএইচইএল ), ম্যাকোস, বিএসডি এবং কয়েকটি এআইএক্সে ভাল কাজ করে :

ps -T $$ | awk 'NR==2{print $NF}' 

বিকল্পভাবে, নীচের একটিকেও কাজ করা উচিত যদি pstree উপলব্ধ থাকে,

pstree | egrep $$ | awk 'NR==2{print $NF}'
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.