在运行时确定脚本中的 shell

在运行时确定脚本中的 shell

据我所知,要确定我们echo $0在 shell 中使用的当前 shell。相反,我希望我的脚本检查它正在哪个 shell 中运行。因此,我尝试$0在脚本中打印,它按应有的方式返回脚本的名称。所以,我的问题是如何找到我的脚本在运行时运行在哪个 shell 中?

答案1

也许不是您所要求的,但这应该在某种程度上可以识别当前正在为某些人进行解释的口译员,例如

  1. 汤普森壳 ( osh),
  2. 伯恩贝壳,
  3. 谍影重重 shell ( bash),
  4. 科恩壳 ( ksh88, ksh93, pdksh, mksh),
  5. zsh,
  6. 符合政策的普通外壳(posh),
  7. 又一个外壳 ( yash),
  8. rc壳,
  9. akanga壳,
  10. es外壳,
  11. wishTCL翻译员、
  12. tclshTCL翻译员、
  13. expectTCL翻译员、
  14. 珀尔,
  15. Python,
  16. 红宝石,
  17. PHP,
  18. JavaScript(至少 Nodejs、SpiderMonkey shell 和 JSPL)
  19. MS/Wine cmd.execommand.com(MSDOS、FreeDOS...)。
'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 年在 usenet 上。 Sven Mascheck 有一个(可能对你更有用)脚本,名为什么壳专注于识别类似 Bourne 的 shell。您还可以找到我们两个脚本的合并版本那里

答案2

在 Linux 上你可以使用/proc/PID/exe.

例子:

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

答案3

这就是我在 .profile 中使用的内容来检查我所使用的系统上的各种 shell。它没有对 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

答案4

如果您的系统上有可用的命令,您可以通过获取父 PID via并解析输出来lsof获取父 shell 可执行文件的完整路径(请参阅pslsof -p $ppid如何确定我正在处理的当前 shell?)。

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

相关内容