O lightdm / gnome / compiz pode usar bash em vez de sh?

3

No meu Ubuntu 12.04, o login é tratado pelo lightdm , que inicia um gnome-session para o usuário que inicia uma compiz instance, que inicia os aplicativos nos quais o usuário clica. Em algum lugar desse caminho, o arquivo .profile é originado, mas quem o origina, está usando /bin/sh , não importa o que /etc/passwd declare como o shell de login do usuário.

Isso é problemático no meu caso. Eu quero definir uma função de shell bash no tempo de login e exportá-lo; então eu crio um ~/.profile :

l() {
  ls -la "$@"
}
export -f l

Mas esse arquivo agora não é lido por bash , como seria de esperar quando /etc/passwd declarasse que meu shell de login é o bash . Não, em vez disso, ele é lido por um sh (que está vinculado a dash no meu caso) e que não pode manipular a instrução export -f l .

Existe uma maneira de tornar lightdm / gnome / compiz honrar meu shell de login como indicado em /etc/passwd em vez de usar o sh ? Existe uma configuração para isso em algum lugar?

    
por Alfe 14.01.2015 / 11:55

1 resposta

1

Como último recurso, você pode substituí-lo imediatamente com bash . Seu .profile poderia começar com

read -r cmd rest < <(cat /proc/$$/cmdline | tr '
if [ ! $(basename $(readlink -f $cmd)) = 'bash' ]; then
  exec /bin/bash --login
fi
0' ' ') if [ ! $(basename $(readlink -f $cmd)) = 'bash' ]; then exec /bin/bash "$rest" fi #... the rest of the .profile script

Eu acredito que deveria funcionar. Teste um pouco.

EDITAR:

A versão anterior não funcionou porque $0 não é o bash que executa o script, mas normalmente o nome do script, e $@ não inclui o nome do script em execução. É por isso que a linha de comando original é obtida de proc , para reproduzir completamente a linha de comando, mas com o primeiro argumento (o shell) substituído por bash, se ainda não é bash (remova if e você tem um infinito recursão).

A leitura desajeitada é feita porque proc usa delimitadores de caracteres nulos em vez de espaços e, assim, torna nossa vida um pouco difícil. Mas não importa.

O shell pai é sobrescrito como o agente smith sobrescreve as pessoas na matriz. Não há mais dash . O PID de dash e tudo nele é assumido por bash . O novo bash executa novamente o script (mas desta vez chega ao fim).

Lembro-me de que .profile não é passado como argumento para bash, mas executado durante a própria inicialização (originado). Você deve rever sua situação particular com cuidado. Talvez seja melhor forçar exec /bin/bash --login a evitar problemas ao ler a linha de comando. Um shell de login deve então ler .profile de qualquer maneira.

A proposta final é, portanto, simplesmente colocar

read -r cmd rest < <(cat /proc/$$/cmdline | tr '
if [ ! $(basename $(readlink -f $cmd)) = 'bash' ]; then
  exec /bin/bash --login
fi
0' ' ') if [ ! $(basename $(readlink -f $cmd)) = 'bash' ]; then exec /bin/bash "$rest" fi #... the rest of the .profile script

no seu .profile no começo e veja o que acontece. O ideal seria que isso não fizesse diferença se o shell de login já fosse bash, mas deveria transparentemente substituir qualquer outro shell com o bash, sem aviso prévio por parte do usuário.

    
por 14.01.2015 / 13:42