我有一个用户switcher
有不同的用例。这PATH
应该取决于当前 shell 是否受限制。因此,我在末尾添加了/home/switcher/.bashrc
:
[[ $- == *r* ]] && PATH='' && echo 'restricted' || echo 'unrestricted'
然而,切换用户时它不能按预期工作:
root@host:~$ sudo -u switcher rbash
unrestricted
switcher@host:~$ echo $PATH
/home/switcher/bin:/usr/local/bin:/usr/bin:/bin
switcher@host:~$ echo $- $SHELL
himrBHs /usr/sbin/nologin
这告诉我.bashrc
实际上已经执行,但显然在 之外rbash
。我这里遗漏了什么?我需要进行哪些更改才能PATH=''
在执行时设置rbash
但不在 中设置bash
?
请注意,遗憾的是,针对不同的用例使用不同的用户对我来说不是一个选择。
答案1
我的测试表明,r
在reads$-
之后会出现,就好像 shell 在处理文件期间没有受到限制一样。这对应于rbash
~/.bashrc
手动的关于限制:
读取任何启动文件后都会强制执行这些限制。
其中一个限制是无法更改PATH
。既然你想更改PATH
,那么稍后强制执行限制对你的情况来说实际上是件好事。似乎r
表示$-
shell 目前受到了有效限制。你想检测它是否将有效限制。您不能将其用于$-
此目的。
有一种机制是专门为你需要做的事情而设计的。它位于shopt
[强调我的]:
restricted_shell
如果 shell 以受限模式启动,则设置此选项 […]。该值不能更改。执行启动文件时不会重置此选项,允许启动文件发现 shell 是否受到限制。
使用方式如下:
shopt -q restricted_shell && PATH='' && echo 'restricted' || echo 'unrestricted'
或更好:
if shopt -q restricted_shell; then
PATH=''
echo 'restricted'
else
echo 'unrestricted'
fi
后者更好,因为第二个echo
仅取决于 的退出状态shopt
。为了比较:在前一个代码片段中(以及在您的原始代码中),第一个失败echo
将触发第二个echo
。对于echo
s 来说,这似乎是微不足道的、无关紧要的或无害的,但如果您添加更多命令,那么一行中有很多 ,&&
如果||
其中一个意外失败,您可能会感到惊讶。
另请注意,打印任何内容.bashrc
都会中断scp
,并且类似的软件(即使打印到 stderr 也可能), 除非你.bashrc
够聪明了。