Экстраполяция

Экстраполяция

Я запускаю новую установку Oneiric (т. е. не обновление) на двух разных системах и сталкиваюсь с одним и тем же набором, казалось бы, связанных проблем.

Самое неприятное из всего этого то, что когда я использую .profile и .bashrc, которые я принес с собой из Mac OS X, вход в X через LightDM немедленно выводит меня из системы. Я полагаю, что это вызвано тем фактом, что при запуске "/bin/sh" он ведет себя как /bin/dash, но при этом переменная $SHELL все еще имеет значение /bin/bash.

Экстраполяция

У меня огромный .bashrc. Вы можете это увидеть.здесьесли хотите, но его содержимое, вероятно, не имеет значения, за исключением того факта, что он полон башизмов и работает без ошибок внутри xterm или на виртуальной консоли.

Мой .profileвыглядит так (сокращенно):

case $SHELL in 
*bash*)
    if [ -f $HOME/.bashrc -a -r $HOME/.bashrc ]; then
        . $HOME/.bashrc
    fi
    ;;
esac

Если я попытаюсь войти в X через LightDM, он немедленно выведет меня обратно. Я получаю ошибки, .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, чтобы я получал одну и ту же среду как для оболочек входа, так и для оболочек без входа, но, очевидно, я хочу, чтобы он загружался только для самой оболочки bash, а не /bin/sh, маскирующейся под bash.

Вы могли заметить разницу в содержании переменных $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, чтобы увидеть, с чем запускается скрипт, и проверить, что он содержит. Переменная $$даст нам 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

Связанный контент