![外推](https://linux22.com/image/959764/%E5%A4%96%E6%8E%A8.png)
我在两个不同的系统上运行全新的 Oneiric 安装(即不是升级),并遇到了同一组看似相关的问题。
最令人沮丧的是,当我使用从 Mac OS X 随身携带的 .profile 和 .bashrc 时,通过 LightDM 登录 X 会立即将我注销。我认为这是因为在运行“/bin/sh”时,它表现为 /bin/dash,但仍然将 $SHELL 变量设置为 /bin/bash。
外推
我有一个巨大的.bashrc
。你可以看到它这里如果你愿意的话,但它的内容可能并不相关,除了它充满了 bashisms,以及它在 xterm 或虚拟控制台中没有任何错误的事实。
我的.profile
样子如下(缩写):
case $SHELL in
*bash*)
if [ -f $HOME/.bashrc -a -r $HOME/.bashrc ]; then
. $HOME/.bashrc
fi
;;
esac
如果我尝试通过 LightDM 登录 X,它会立即将我注销。我收到.xsession-errors
与 .bashrc 相关的错误,如下所示(缩写):
/home/mrled/.bashrc: 103: [[: not found
[: 103: Linux: unexpected operator
[: 274: -P :: unexpected operator
/home/mrled/.bashrc: 520: complete: not found
正如我所说,当我从虚拟控制台运行 bash 时,我不会收到这些错误。此外,如果我删除 .profile,我就可以正常登录 X。(我也可以登录虚拟控制台并使用它启动startx
一个有效的 X 会话,但这当然不是长期的解决方案。)
然而,我发现如果我跑步/bin/sh -l
,我做获取错误。下面是示例会话(注意:我已将 bash 提示符简化为bash>
,而 sh 提示符仅为$
):
bash> echo $SHELL
/bin/bash
bash> echo $BASH_VERSION
4.2.10(1)-release
bash> /bin/sh -l
/home/mrled/.bashrc: 103: [[: not found
[: 103: Linux: unexpected operator
[: 274: -P :: unexpected operator
/home/mrled/.bashrc: 520: complete: not found
$ echo $SHELL
/bin/bash
$ echo $BASH_VERSION
$
问题1:为什么会发生这种情况?
我明白那个/bin/sh 现在指向 dash 而不是 bash,但如果这是真的,那为什么$SHELL
还要回来/bin/bash
?
问题 2:我该怎么做才能解决这个问题?
有办法解决这个问题吗?我想让我的配置文件继续加载 .bashrc,以便在登录和非登录 shell 上获得相同的环境,但显然我只希望它为 bash 本身加载,而不是为伪装成 bash 的 /bin/sh 加载。
您可能已经注意到了上述 $BASH_VERSION 变量内容的差异。我尝试将 .profile 包装成如下内容:
if [ -n $BASH_VERSION ]; then
# the rest of my .profile as above
fi
-n
仅当字符串长度非零时,测试才应返回 true,但是,即使在上面的会话中,当我在它下运行时,它为/bin/sh -l
$BASH_VERSION 返回一个空字符串,当它像这样包含在我的 .profile 中时,它通过了测试!然后它继续获取我的 .bashrc 并给出与以前相同的错误。
现在我真的使困惑。
答案1
$BASH_VERSION
您可以使空白的事实dash
为您工作:
if [ "$BASH_VERSION" = '' ]; then
echo "This is dash."
else
echo "This is bash."
fi
答案2
您只需要在变量上使用引号BASH_VERSION
即可使用-n
if [ -n "$BASH_VERSION" ];then
echo "this is bash";
else
echo "this is dash";
fi
答案3
使用/proc/[PID]/cmdline
查看脚本正在运行的内容并测试其包含的内容。$$
变量将为我们提供正在运行的 shell 的 PID。因此,我们可以编写如下脚本,
#!/bin/bash
if grep -q 'bash' /proc/$$/cmdline ;
then
echo "This is bash"
else
echo "This is some other shell"
fi
以下是对同一脚本的测试:
$> bash test_script.sh
This is bash
$> dash test_script.sh
This is some other shell