答案 0 :(得分:706)
答案 1 :(得分:85)
答案 2 :(得分:35)
尝试
ps -p $$ -oargs=
或
ps -p $$ -ocomm=
答案 3 :(得分:23)
如果您只是想确保用户使用bash调用脚本:
if [ ! -n "$BASH" ] ;then echo Please run this script $0 with bash; exit 1; fi
答案 4 :(得分:19)
答案 5 :(得分:11)
$SHELL
无需始终显示当前的shell。它只反映了要调用的默认shell。
要测试上述内容,Say bash
是默认shell,请尝试echo $SHELL
,然后在同一个终端中,进入其他shell(例如ksh)并尝试$SHELL
,在这两种情况下,你都会看到结果为bash。
要获取当前shell的名称,请使用cat /proc/$$/cmdline
以及readlink /proc/$$/exe
答案 6 :(得分:9)
答案 7 :(得分:8)
我有一个简单的技巧来找到当前的shell。只需键入随机字符串(不是命令)。它将失败并返回"未找到"错误,但在行的开头,它将说明它是哪个shell:
ksh: aaaaa: not found [No such file or directory]
bash: aaaaa: command not found
答案 8 :(得分:7)
这将始终给出实际使用的shell - 获取实际可执行文件的名称而不是shell名称(即ksh93
而不是ksh
等。)/bin/sh
将显示实际使用的shell:ie dash
ls -l /proc/$$/exe | sed 's%.*/%%'
我知道有很多人说ls
输出应该是新处理的,但是你有一个使用特殊字符命名的shell或者放在一个用特殊字符命名的目录中的概率是多少?如果仍然是这种情况,这里还有很多其他的例子。不同的。
答案 9 :(得分:4)
我尝试了很多不同的方法,对我来说最好的方法是:
ps -p $$
它也可以在 Cygwin 下工作,并且不会产生误报作为PID grepping。通过一些清理,它只输出一个可执行文件名称(在带有路径的 Cygwin 下):
ps -p $$ | tail -1 | awk '{print $NF}'
您可以创建一个功能,这样您就不必记住它:
# print currently active shell
shell () {
ps -p $$ | tail -1 | awk '{print $NF}'
}
...然后只执行shell
。
在Debian和Cygwin下测试。
答案 10 :(得分:4)
我打印父进程的变体。
ps -p $$ | awk '$1 == PP {print $4}' PP=$$
为什么运行不必要的应用程序,'awk'可以为你做什么?
答案 11 :(得分:3)
如果您的/bin/sh
支持POSIX标准并且您的系统安装了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}'
答案 12 :(得分:2)
答案 13 :(得分:1)
我特别喜欢 Nahuel Fouilleul 的解决方案,但我必须在带有内置 Bash shell 的 Ubuntu 18.04 上运行它的以下变体:
bash -c 'shellPID=$$; ps -ocomm= -q $shellPID'
没有临时变量 shellPID
,例如以下内容:
bash -c 'ps -ocomm= -q $$'
只会为我输出 ps
。也许你们不是都在使用非交互模式,这会有所作为吗?
答案 14 :(得分:1)
请执行以下操作,了解您的Shell是否使用DASH / BASH。
1) ls -la / bin / sh , 如果结果是 / bin / sh - > / bin / bash ==>然后你的shell使用BASH。
如果结果是 / bin / sh - > / bin / dash ==>然后你的shell正在使用DASH。
如果您想从BASH更改为DASH,反之亦然,请使用以下代码 ln -s / bin / bash / bin / sh (将shell更改为BASH)
注意:如果上述命令导致错误,/ bin / sh已存在,请删除/ bin / sh并重试。
答案 15 :(得分:1)
有很多方法可以找到shell及其相应的版本。这里有一些对我有用。
直接前进
Hackish方法
$> *******(键入一组随机字符,在输出中你将获得shell名称。在我的情况下 -bash:chapter2-a-sample-isomorphic-app:command not found )
答案 16 :(得分:1)
没有一个答案适用于fish
shell(它没有变量$$
或$0
)。
这适用于我(在sh
,bash
,fish
,ksh
,csh
,true
,{{1}上测试}和tcsh
; openSUSE 13.2):
zsh
此命令输出类似ps | tail -n 4 | sed -E '2,$d;s/.* (.*)/\1/'
的字符串。我在这里只使用bash
,ps
和tail
(没有GNU extes;尝试添加sed
来检查它)。它们都是标准的POSIX命令。我确定--posix
可以删除,但我的tail
fu不够强大,无法执行此操作。
在我看来,这个解决方案不是很便携,因为它在OS X上不起作用。:(
答案 17 :(得分:1)
我的解决方案:
ps -o command | grep -v -e "\<ps\>" -e grep -e tail | tail -1
这应该可以跨不同平台和shell移植。它像其他解决方案一样使用ps
,但它不依赖于sed
或awk
并过滤掉管道和ps
本身的垃圾,以便shell始终是最后一个条目这样我们就不需要依赖非便携式PID变量或选择正确的行和列。
我已经使用bash,zsh和fish在Debian和MacOS上进行了测试(这些解决方案不适用于大多数这些解决方案,而没有专门针对fish更改表达式,因为它使用了不同的PID变量)。
答案 18 :(得分:1)
这不是一个非常干净的解决方案,但可以做你想要的。
我意识到2015年这个好老的答案有点晚了,但是......
#MUST BE SOURCED..
getshell() {
local shell="`ps -p $$ | tail -1 | awk '{print $4}'`"
shells_array=(
# It is important that the shells are listed by the decrease of their length name.
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的shell。
答案 19 :(得分:1)
从&#34; ps&#34;的输出中获取PID不需要因为您可以从/ proc目录结构中读取任何PID的相应命令行:
echo $(cat /proc/$$/cmdline)
但是,这可能不仅仅是简单:
echo $0
关于运行实际上与名称不同的shell,一个想法是使用您之前获得的名称从shell请求版本:
<some_shell> --version
sh似乎失败了,退出代码2,而其他人给了一些有用的东西(但我无法验证所有,因为我没有它们):
$ sh --version
sh: 0: Illegal option --
echo $?
2
答案 20 :(得分:1)
如果您只是想检查您是否正在运行(特定版本)Bash,
最好的方法是使用$BASH_VERSINFO
数组变量。
作为(只读)数组变量,它不能在环境中设置,
所以你可以确定它来自当前的shell(如果有的话)。
但是,由于Bash在调用sh
时具有不同的行为,
您还需要检查$BASH
环境变量以/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
你可以在第一种情况下省略对某些功能的偏执功能检查, 并假设未来的bash版本是兼容的。
答案 21 :(得分:1)
答案 22 :(得分:0)
请使用以下命令:
# ps -p $$ | tail -1 | awk '{print $4}'
答案 23 :(得分:0)
我想出了这个
sed 's/.*SHELL=//; s/[[:upper:]].*//' /proc/$$/environ
答案 24 :(得分:0)
为什么不使用 $SHELL
变量获取它,一个简单的 sed 可以删除路径:
$ echo $SHELL | sed -E 's/^.*\/([aA-zZ]+$)/\1/g'
bash
在 MacOS、Ubuntu、CentOS 上测试
答案 25 :(得分:0)
一种方法是:
ps -p $$ -o exe=
IMO 比另一个答案中建议的使用 -o args
或 -o comm
更好(这些可能使用例如一些符号链接,例如当 /bin/sh
指向某个特定的 shell 作为破折号或 bash) .
以上返回可执行文件的路径,但要注意,由于 /usr-merge,可能需要检查多个路径(例如 /bin/bash
和 /usr/bin/bash
)
另请注意,上述内容并不完全兼容 POSIX(POSIX ps 没有 exe
)。
答案 26 :(得分:-2)
这个适用于RHEL,MacOS,BSD和一些AIXes
ps -T $$ | awk 'NR==2{print $NF}'
或者,如果pstree可用,则下一个也应该有效,
pstree | egrep $$ | awk 'NR==2{print $NF}'