当我读到你的问题时,我的第一个念头是$SHLVL
。然后,我看到你想算vim
的水平
,除了外壳的水平。一种简单的方法是定义一个shell函数:
vim() { ( ((SHLVL++)); command vim "$@");}
SHLVL
每次键入vim
命令时,它都会自动无提示地增加。您将需要对所使用的vi
/的每个变体进行此操作vim
;例如,
vi() { ( ((SHLVL++)); command vi "$@");}
view() { ( ((SHLVL++)); command view "$@");}
括号的外部集会创建一个子外壳,因此手动更改其值SHLVL
不会污染当前(父)外壳环境。当然,存在command
关键字可以防止函数调用自身(这将导致无限递归循环)。当然,您应该将这些定义放入您的.bashrc
或其他Shell初始化文件中。
上面的代码效率低下。如果您说,在某些壳中(bash是一个)
(cmd 1 ; cmd 2 ; … ; cmd n)
在外部可执行程序(即不是内置命令)的地方,shell保留了一个额外的进程,只是为了等待终止。(可以说)这是没有必要的;优点和缺点是有争议的。如果您不介意占用一点内存和一个进程插槽(并在执行时看到一个比您需要的shell进程更多的进程),请执行上述操作并跳到下一部分。如果您使用的Shell不能保持多余的进程不变,则同上。但是,如果您想避免多余的过程,首先要尝试的是cmdn
cmdn
ps
vim() { ( ((SHLVL++)); exec vim "$@");}
该exec
命令可以防止多余的Shell进程留下来。
但是,有一个陷阱。Shell的处理SHLVL
有些直观:Shell启动时,会检查是否SHLVL
设置了。如果未设置(或设置为数字以外的值),则外壳程序将其设置为1。如果将其设置为(设置为数字),则外壳程序将其加1。
但是,按照这种逻辑,如果您说exec sh
,您SHLVL
应该上升。但这是不可取的,因为您的实际外壳级别没有增加。外壳由处理这一减去一个从 SHLVL
当你这样做的exec
:
$ echo "$SHLVL"
1
$ set | grep SHLVL
SHLVL=1
$ env | grep SHLVL
SHLVL=1
$ (env | grep SHLVL)
SHLVL=1
$ (env) | grep SHLVL
SHLVL=1
$ (exec env) | grep SHLVL
SHLVL=0
所以
vim() { ( ((SHLVL++)); exec vim "$@");}
是洗;它SHLVL
只会递增以再次递减。您可能只是说而已vim
,而没有功能的好处。
注意:
根据StéphaneChazelas(谁都知道)的说法,如果shell在子shell中,那么一些shell足够聪明以至于无法执行此操作exec
。
要解决此问题,您需要
vim() { ( ((SHLVL+=2)); exec vim "$@");}
然后,我看到你想算vim
水平
独立的外壳水平。好吧,完全相同的技巧也起作用(好,做了一些小修改):
vim() { ( ((SHLVL++, VILVL++)); export VILVL; exec vim "$@");}
(等对vi
,view
等)的export
,因为有必要VILVL
不被定义为默认的环境变量。但这并不需要成为功能的一部分。您可以说export VILVL
成是单独的命令(在中.bashrc
)。而且,如上所述,如果多余的shell程序对您来说不是问题,则您可以command vim
代替exec vim
,而SHLVL
不必理会:
vim() { ( ((VILVL++)); command vim "$@");}
个人偏好:
您可能想重命名VILVL
为VIM_LEVEL
。当我看着“ VILVL
”时,我的眼睛受伤了。他们无法分辨这是“乙烯基”的拼写错误还是罗马数字格式错误。
如果您使用的外壳程序不支持SHLVL
(例如破折号),则只要外壳程序实现启动文件,就可以自己实现。只是做类似的事情
if [ "$SHELL_LEVEL" = "" ]
then
SHELL_LEVEL=1
else
SHELL_LEVEL=$(expr "$SHELL_LEVEL" + 1)
fi
export SHELL_LEVEL
在您.profile
或适用的文件中。(您可能不应该使用该名称SHLVL
,因为如果您开始使用支持的外壳,这将导致混乱SHLVL
。)
其他答案已经解决了将环境变量值嵌入到您的shell提示中的问题,因此我不再重复,特别是您说您已经知道如何做。
$SHLVL
您要查找的变量(由多个shell维护)是什么?