রানটাইমের সময় স্ক্রিপ্টে শেল নির্ধারণ করুন


22

আমার জ্ঞান অনুসারে, শেলটি ব্যবহার করে বর্তমান শেলটি নির্ধারণ করতে echo $0। বরং আমি চাই আমার স্ক্রিপ্টটি কোন শেলটি চলছে তা যাচাই করা উচিত। সুতরাং, আমি $0স্ক্রিপ্টে মুদ্রণের চেষ্টা করেছি এবং এটি স্ক্রিপ্টটির নামটি যেমনটি করা উচিত তেমন ফিরিয়ে দেয়। সুতরাং, আমার প্রশ্নটি কীভাবে আমি খুঁজে পেতে পারি যে রানটাইমের সময় আমার স্ক্রিপ্টটি কোন শেলটি চলছে?


আপনি কোন স্ক্রিপ্টিং ভাষা ব্যবহার করছেন? এছাড়াও, আরও খারাপ ক্ষেত্রে, আপনি স্ক্রিপ্টের অভ্যন্তরে "প্রতিধ্বনি $ 0" ফলাফল পেতে সিস্টেম কমান্ডটি সর্বদা শেল আউট করতে পারেন।
ব্রিগুই

echo $0এখানে কোনও বিকল্প নয়, কারণ স্ক্রিপ্টটি বিভিন্ন মেশিনে চলবে যেখানে প্রথমে আমার যাচাই করা দরকার তা হ'ল শেল।
g4ur4v

তাহলে স্ক্রিপ্টিং ভাষাটি কী?
ব্রিগুই

@ ব্রিজুই: এটি একটি ইউনিক্স শেল স্ক্রিপ্ট।
g4ur4v

3
ঠিক আছে, আপনি যদি #! /bin/sh -শীর্ষে যোগ করেন তবে এটি চলবে sh। আপনি কি বোঝাতে চান এটির রূপটিsh
স্টাফেন শেজেলাস

উত্তর:


28

লিনাক্সে আপনি ব্যবহার করতে পারেন /proc/PID/exe

উদাহরণ:

# readlink /proc/$$/exe
/bin/zsh

3
এটি আমার জন্য কিছুটা সুনির্দিষ্ট (যেমন ডিবিয়ান এটি zsh4 বা ksh93 প্রিন্ট করে)। /bin/sed -r -e 's/\x0.*//' /proc/$$/cmdlineপরিবর্তে zsh বা ksh দেয়। (শেলগুলি পরিবর্তে স্ক্রিপ্টগুলির নাম দেওয়ার জন্য যদি শেলগুলি যাদুতে এটি ঠিক না করে) তবে এটি 0 ডলার হবে।
frostschutz

@frostschutz আপনার সেরা উত্তর, 500 এর জন্য চালান!
তেরেসা ই জুনিয়র

5
এটি ভয়ঙ্কর সমস্ত বিশ্বের লিনাক্স বক্স রোগে ভুগছে। /procএটি যতটা কুৎসিত এবং অপরিশোধনযোগ্য তা পায়।
জেনস

7
@ জেনস সেই কারণেই আমি এটি নির্দিষ্ট করে কেবল লিনাক্সের জন্য। /proc'কুশ্রী' নয়। /procপ্রায়শই খুব মার্জিত সমাধান। হ্যাঁ বহনযোগ্য নয়, তবে কিছু অপ্রয়োজনীয় কারণ এটি কুশ্রী করে তোলে না।
প্যাট্রিক

3
@ পেট্রিককে আমি কুরুচিপূর্ণ বলে বিবেচনা করি /procকারণ এতে থাকা ফাইলগুলি বিকাশকারীদের কৌতূহলে আসতে পারে এবং ফাইলগুলির বিষয়বস্তু কোনও বিজ্ঞপ্তি ছাড়াই পরিবর্তিত হওয়ার ঝুঁকিপূর্ণ, বিট্রোট এবং চলমান টার্গেট ফাইল ফর্ম্যাটগুলির কারণে অবিরাম ব্যথা সৃষ্টি করে।
জেনস

48

সম্ভবত আপনি যা চাইছেন তা নয়, তবে থম্পসন (osh), বোর্ন, বোর্ন-আবার (বাশ), কর্ন (ksh88, ksh93, pdksh, mksh) এর মতো কিছু সংখ্যক ব্যক্তির জন্য বর্তমানে এটি দোভাষীকে ব্যাখ্যা করার জন্য এটি কিছুটা হলেও কাজ করা উচিত ), জেডএস, পলিসি-কমপ্লিনেন্ট অর্ডিনারি (পশ), তবুও আরেকটি (যশ), আরসি, আকঙ্গা, এস শেলস, ইচ্ছুক, tclsh, আশা, পার্ল, পাইথন, রুবি, পিএইচপি, জাভাস্ক্রিপ্ট (নোডেজ, স্পাইডারমোনকি শেল এবং জেএসপিএল অন্তত) , এমএস / ওয়াইন সেমিডি.এক্সই, কমান্ড ডটকম (এমএসডিএস, ফ্রিডস ...)।

'echo' +"'[{<?php echo chr(13)?>php <?php echo PHP_VERSION.chr(10);exit;?>}\
@GOTO DOS [exit[set 1 [[set 2 package] names];set 3 Tcl\ [info patchlevel];\
if {[lsearch -exact $1 Expect]>=0} {puts expect\ [$2 require Expect]\ ($3)} \
elseif {[lsearch -exact $1 Tk]>=0} {puts wish\ ($3,\ Tk\ [$2 require Tk])} \
else {puts $3}]]]' >/dev/null ' {\">/dev/null \
">"/dev/null" +"\'";q="#{",1//2,"}";a=+1;q='''=.q,';q=%{\"
'echo' /*>/dev/null
echo ">/dev/null;status=0;@ {status=1};*=(" '$' ");~ $status 1&&{e='"\
"';eval catch $2 ^'&version {eval ''echo <='^ $2 ^'&version''}';exit};e='"\
"';if (eval '{let ''a^~a''} >[2] /dev/null'){e='"\
"';exec echo akanga};eval exec echo rc $2 ^ version;\" > /dev/null
: #;echo possibly pre-Bourne UNIX V1-6 shell;exit
if (! $?version) set version=csh;exec echo $version
:DOS
@CLS
@IF NOT "%DOSEMU_VERSION%"=="" ECHO DOSEMU %DOSEMU_VERSION%
@ECHO %OS% %COMSPEC%
@VER
@GOTO FIN
", unless eval 'printf "perl %vd\n",$^V;exit;'> "/dev/null";eval ': "\'';
=S"';f=false e=exec\ echo n=/dev/null v=SH_VERSION;`(eval "f() { echo :
};f")2>$n` $f||$e Bourne-like shell without function
case `(: ${_z_?1}) 2>&1` in 1) $e ash/BSD sh;;esac;t(){
eval "\${$1$v+:} $f &&exec echo ${2}sh \$$1$v";};t BA ba;t Z z;t PO po;t YA ya
case `(typeset -Z2 b=0;$e $b)2>$n` in 00) (eval ':${.}')2>$n&&eval '
$e ksh93 ${.sh.version}';t K pdk;$e ksh88;;esac;case `(eval '$e ${f#*s}$($e 1
)$((1+1))')2>$n` in e12)$e POSIX shell;;esac;$e Bourne-like shell;: }
print "ruby ",RUBY_VERSION,"\n";exit;' ''';import sys
print("python "+sys.version);z='''*/;
s="";j="JavaScript";if(typeof process=="object"){p=console.log;p(process.title
,process.version)}else{p=print;p((f="function")==(t=typeof version)?"string"==
typeof(v=version())?v:(typeof build!=f?"":s= "SpiderMonkey ")+j+" "+v:(t==
"undefined"?j+"?":version)+"\n");if(s)build()}/*
:FIN } *///'''

আমি ইউটিনেটে যা_ইন্টারপ্রিটার স্ক্রিপ্ট সার্কা 2004 এর প্রাথমিক সংস্করণ পোস্ট করেছি । সোভেন মাসচেকের বোর্ন-জাতীয় শেল শনাক্তকরণের দিকে মনোনিবেশ করে এমন একটি (যা সম্ভবত আপনার পক্ষে আরও কার্যকর) স্ক্রিপ্ট রয়েছে । আপনি আমাদের দুটি স্ক্রিপ্টের একত্রীকরণ সংস্করণটিও সেখানে পেতে পারেন


3
এটি পাইথন 3, কেবল পাইথন 2 সনাক্ত করতে পারে না that এটি ঠিক করতে, printএকটি ফাংশন হিসাবে পরিবর্তন করুন ।
ক্রিস ডাউন

39
এটি এখন পর্যন্ত বছরের বৃহত্তম ডাব্লুটিএফ মুহূর্ত। অত্যাধিক বিগ্রহ বহনযোগ্যতার জন্য +1।
l0b0

1
এটি ফিশ শেলকে চিনতে পারলে ভাল লাগবে।
কনরাড বোরোস্কি

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

4
@ আইকোনোক্লাস্ট, সুতরাং এটি bash 3.2.53(1)-releaseদোভাষী হিসাবে এটি ব্যাখ্যা করে সঠিকভাবে চিহ্নিত করে।
স্টাফেন চেজেলাস

12

আমি কাজ করি এমন সিস্টেমে বিভিন্ন শেলগুলি পরীক্ষা করার জন্য আমি আমার প্রোফাইলে এটি ব্যবহার করি। এটি ksh88 এবং ksh93 এর মধ্যে সূক্ষ্ম পার্থক্য তৈরি করে না তবে এটি কখনও আমাকে ব্যর্থ করে না।

মনে রাখবেন যে এটির জন্য একক কাঁটাচামচ বা পাইপের প্রয়োজন নেই।

# Determine what (Bourne compatible) shell we are running under. Put the result
# in $PROFILE_SHELL (not $SHELL) so further code can depend on the shell type.

if test -n "$ZSH_VERSION"; then
  PROFILE_SHELL=zsh
elif test -n "$BASH_VERSION"; then
  PROFILE_SHELL=bash
elif test -n "$KSH_VERSION"; then
  PROFILE_SHELL=ksh
elif test -n "$FCEDIT"; then
  PROFILE_SHELL=ksh
elif test -n "$PS3"; then
  PROFILE_SHELL=unknown
else
  PROFILE_SHELL=sh
fi

1
নোট করুন যে শুধুমাত্র খুব সাম্প্রতিক সংস্করণ ksh93আছে $KSH_VERSION। এই পরিবর্তনশীলটি pdkshএটি এবং টি কেএস 88 এ আসে নি এবং এটি কখনও তৈরি হয়নি।
স্টাফেন চেজেলাস 21

ঠিক আছে, যে কারণে আমি দ্বিতীয় পরীক্ষা আছে FCEDIT
জেনস

1
ঠিক। দ্রষ্টব্য: posh(বেশিরভাগ নন-পসিক্স বৈশিষ্ট্যযুক্ত পিডিএক্সএক্স মুছে ফেলা হয়েছে তাই আপনি সম্ভবত এটি "শ" বলতে চাইবেন) এর কোনও এফসিইডিআইটি বা কেএসএইচ_ভার্সন নেই তবে পিএস 3 রয়েছে (সম্ভবত দীর্ঘকালীন নয়), যদিও এটির জন্য এটি লগইন শেল হিসাবে পাওয়ার সম্ভাবনা কম unlikely । এছাড়াও মনে রাখবেন উপরের কোড কিনা প্রতিফলিত না bashবা zshহয় shএমুলেশন মোড, যা একটি সমস্যা হতে পারে যদি আপনি ব্যবহার করছেন $PROFILE_SHELLহোক বা না হোক এটা বা ওটা বৈশিষ্ট্যটি সক্ষম করতে সিদ্ধান্ত নিতে। আপনি যা পরীক্ষা করতে চান (বা নাও করতে পারেন) তার জন্য সুইভেন মাসচেকের যা কিছু আছে তা দেখুন।
স্টাফেন চেজেলাস

6

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

ps -o args= -p "$$"

যা আপনাকে স্ক্রিপ্টের পিডের সাথে যুক্ত কমান্ডের নাম দেবে।


আমি যতদূর বলতে পারি শেবাং ব্যবহার করার সময় কাজ করে না। sprunge.us/QeHD
ক্রিস ডাউন

দুঃখিত, @ ক্রিসডাউন, ফ্লপ। আমার খারাপ, উত্তরটি POSIXififier cmdকরার commসময় আমি ভুলভাবে অনুবাদ করেছি ।
স্টাফেন চেজেলাস

1

যদি lsofআপনার সিস্টেমে কমান্ডটি উপলভ্য থাকে তবে আপনি প্যারেন্ট পিআইডি পেয়ে psএবং আউটপুটকে বিশ্লেষণ করে প্যারেন্ট শেলটির পুরো পথ নির্বাহ করতেlsof -p $ppid পারেন (দেখুন আমি যে বর্তমান শেলটি নিয়ে কাজ করছি তা কীভাবে নির্ধারণ করবেন? )।

#!/bin/sh
ppid="`ps -p "$$" -o ppid=`"
lsof -nP -p "$ppid" | awk 'NR==3 {print $NF; exit}'

আমার সিস্টেমে এটি প্রত্যাবর্তন করে /, আমি যদি ব্যবহার NR==4করি তবে আমি শাঁস পিতামাতার পথ পাই।
থোর

নোট করুন যে পসিক্স shএর $PPIDভেরিয়েবল রয়েছে। চালু Linux, আপনি ব্যবহার করতে পারেন readlink -f "/proc/$PPID/exe"
স্টাফেন চেজেলাস

1

লিনাক্সের বাইরে বা / প্রো ফাইল সিস্টেম বা অ্যাকুইভ্যালেন্টে অ্যাক্সেসের অভাব, আপনি pstree ব্যবহার করতে পারেন:

ধরে নিচ্ছি আপনার পিড আছে

একটি ম্যাকে:

./test.sh 
16012
-+= 00001 root /sbin/launchd
 \-+= 00245 wingwong /sbin/launchd
   \-+= 04670 wingwong /Applications/Utilities/Terminal.app/Contents/MacOS/Terminal -psn_0_2052597
     \-+= 11816 root login -pf wingwong
       \-+= 11817 wingwong -bash
         \-+= 16012 wingwong ksh ./test.sh
           \-+- 16013 wingwong pstree -p 16012

একটি লিনাক্স বাক্সে:

./test.sh 
14981
bash(14981)---pstree(14982)

আপনার পরিবেশের উপর নির্ভর করে pstree থেকে আউটপুটটির বিন্যাস এবং শৈলী পৃথক, তবে আপনি ASCII আউটপুট এবং তারপরে সেড / টিআর / অ্যাজক / ইত্যাদি প্রয়োগ করতে পারেন। স্ক্রিপ্টটি চালিত শেলটি পেতে আউটপুট ফিল্টার করুন।

সুতরাং একটি পরিষ্কার করা আউটপুট সংস্করণ (ম্যাক বা লিনাক্স ওএসের জন্য কাজ করে):

#!/usr/bin/env sh
pstree  -p $$  | tr ' ()' '\012\012\012' | grep -i "sh$" | grep -v "$0" | tail -1

রান ফলন:

./test.sh 
sh

এবং যখন অন্য কোনও শেল দিয়ে চালিত হয়:

#!/usr/bin/env ksh
pstree  -p $$  | tr ' ()' '\012\012\012' | grep -i "sh$" | grep -v "$0" | tail -1

উৎপাদনের:

./test.sh 
ksh

কোনও রুট বা বিশেষ ফাইল সিস্টেমের প্রয়োজন নেই। দ্রষ্টব্য, আমার ফিল্টারিংটি ধরে নেওয়া হয় যে শেলের বাইনারি নামটি sh এর সাথে শেষ হয় এবং কোনও মধ্যবর্তী এন্ট্রি নেই যা শ এর সাথে শেষ হয়। এছাড়াও ধরে নিন যে আপনি আপনার স্ক্রিপ্টটির নাম "sh" বা কিছু দুর্ভাগ্যজনক গ্রেপ প্যাটার্ন রাখেন নি যা তথ্যকে বিলোপ করবে। :) উচ্চতর ডিগ্রিপ্রুফিং নিশ্চিত করতে আপনার নিজের পরিবেশের জন্য কিছু কাস্টমাইজেশন প্রয়োজন।


-2

আপনি কমান্ডটি ব্যবহার করতে পারেন:

$ echo $SHELL

স্ক্রিপ্টের মধ্যে থেকে শেলটি সন্ধান করতে।


18
না $SHELLএটি ব্যবহারকারীর পছন্দের শেল the ব্যবহারকারীর লগইন শেল থেকে শুরু করা। বর্তমানে চলমান শেলটির সাথে কিছুই করার নেই।
স্টাফেন চেজেলাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.