外推

外推

我在两个不同的系统上运行全新的 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

相关内容