Por que o Bash não conseguiu localizar o comando mesmo que $ PATH esteja especificado corretamente?

9

Estou especificando o caminho para o meu comando no arquivo / etc / profile :

export PATH=$PATH:/usr/app/cpn/bin

Meu comando está localizado em:

$ which ydisplay 
/usr/app/cpn/bin/ydisplay

Então, quando eu executo a saída "echo $ PATH" é parecido com:

$ echo $PATH
...:/usr/app/cpn/bin

E está tudo bem, mas quando estou tentando iniciar meu comando via SSH, estou recebendo um erro:

$ ssh 127.0.0.1 ydisplay
$ bash: ydisplay: command not found

Mas o meu caminho ainda está presente:

$ ssh 127.0.0.1 echo $PATH
...:/usr/app/cpn/bin

Por favor, me explique por que o Bash não consegue encontrar o ydisplay durante a sessão do SSH e como configurar corretamente o SSH para evitar esse problema.

Mais, se eu especificar $ PATH no arquivo local .bashrc no usuário atual, tudo funciona corretamente. Mas eu quero modificar apenas um arquivo, especificando vários arquivos para cada usuário. É por isso que estou perguntando.

    
por SIGSEGV 23.08.2012 / 10:22

2 respostas

5

tl; dr

Executando ssh 127.0.0.1 ydisplay sources ~/.bashrc em vez de /etc/profile . Altere seu caminho em ~/.bashrc .

detalhes

A única vez que /etc/profile é lido é quando seu shell é um "login shell".

Do Manual de referência do bash :

When bash is invoked as a login shell, ... it first reads and executes commands from the file /etc/profile

Mas quando você executa ssh 127.0.0.1 ydisplay , bash não é iniciado como um shell de login. No entanto, ele lê um arquivo de inicialização diferente. O Manual de referência do bash diz:

when ... executed by ... sshd. ... it reads and executes commands from ~/.bashrc

Então, você deve colocar as configurações de PATH em ~/.bashrc .

Na maioria dos sistemas, ~/.bash_profile sources ~/.bashrc , você pode colocar suas configurações apenas em ~/.bashrc em vez de colocá-las em ambos os arquivos.

Não há uma maneira padrão de alterar a configuração para todos os usuários, mas a maioria dos sistemas tem /etc/bashrc , /etc/bash.bashrc ou similar.

Caso contrário, configure pam_env e coloque a configuração PATH em /etc/environment .

Veja também:

por 23.08.2012 / 16:41
1

Historicamente, os arquivos de perfil ( /etc/profile e ~/.profile ) foram invocados quando você efetuou login (no console de texto, o que mais?) e serviu muitos propósitos:

  • Defina variáveis de ambiente e outros parâmetros (por exemplo, umask) para a sessão.
  • Execute programas extras no início da sessão (por exemplo, notificação por e-mail).
  • Execute o programa para a sessão, se for diferente do shell (por exemplo, outro shell ou X Window).
  • Defina os parâmetros do terminal (por exemplo, stty ).
  • Defina os parâmetros da shell (por exemplo, aliases).

Todos esses propósitos não foram identificados como separados até mais tarde. Porque os scripts de perfil podem fazer coisas que só fazem sentido em uma sessão interativa (interação terminal, inicie outros programas), quando invocação de shell remota ( rsh ) foi introduzido, os makes do rsh decidiram não invocar o shell remoto como um shell de login, para que os scripts de perfil não sejam executados. (Algumas versões de rshd têm uma opção para executar o shell remoto como um shell de login.) Ssh copiou esse comportamento para ser um substituto substituto para o rsh.

Se você deseja ter seus scripts de perfil executados, pode invocá-los explicitamente.

ssh 127.0.0.1 '. /etc/profile; . ~/.profile; ydisplay'

Observe o comando . para carregar os scripts de perfil dentro do shell: eles são comandos a serem executados dentro daquele shell, não um programa externo.

Se você deseja definir uma variável de ambiente globalmente para todos os usuários, há outro método em muitos sistemas: em vez de defini-la em /etc/profile , defina-a em /etc/environment . Este arquivo é lido através do módulo pam_env ; a maioria das distribuições do Linux está configurada para lê-lo.

Se o seu login shell é bash, existe uma outra possibilidade. Normalmente, você não deve definir variáveis de ambiente em .bashrc (porque elas não serão definidas em sessões X, exceto se você passar por um terminal com um shell interativo, porque elas não serão definidas se você efetuar login interativamente em um console de texto ou por ssh, porque elas substituirão as configurações personalizadas se você invocar um shell dentro de outro programa ). No entanto, o bash tem um recurso estranho que eu nunca entendi: ele lê ~/.bashrc em duas circunstâncias não relacionadas:

  • em shells interativos que não são shells de login;
  • em shells não interativos que não são shells de login, se o bash pensar que ele foi chamado por rshd ou sshd .

Quando você executa um comando sobre o ssh, você está no segundo caso. Você pode solicitar que seu perfil seja lido lendo /etc/profile e .profile de .bashrc . Inclua o seguinte código no seu ~/.bashrc :

case $- in
  *i*) :;; # this is an interactive shell, fine
  *) # This is not an interactive shell! This must be a non-interactive remote shell session.
    . /etc/profile; . ~/.profile
    return;;
esac
    
por 26.08.2012 / 18:31