Execute um comando em um shell interativo com ssh após a fonte .bashrc

11

Eu quero ssh em um computador Ubuntu remoto, fonte meu .bashrce executar um comando que depende dos parâmetros definidos por isso .bashrc. Tudo isso em um shell interativo que não fecha após a conclusão do comando.

O que eu tentei até agora é

ssh user@remote_computer -t 'bash -l -c "my_alias;bash"'

ou apenas

ssh user@remote_computer -t "my_alias;bash"

Isso funciona para comandos gerais (como lspor exemplo), mas quando tento executar um alias definido em .bashrc, recebo um erro:

bash: my_alias: command not found

Mas quando eu escrevo manualmente novamente e o executo, ele funciona!

Então, como posso ter certeza de que a .bashrcfonte é originada antes que o comando seja chamado?

Mehdi
fonte
A postagem é confusa. Eu recomendo não abusar da execução de comandos como esse; no entanto, se o comando bash ou bash estiver sendo chamado, eu diria que o .bashrc deve ser executado. Evidentemente, existem algumas diferenças ou peculiaridades na execução de um comando como esse e, para aplicações mais sérias, eu recomendaria Ansible ou fantoche.
Rui F Ribeiro
Eu editei minha pergunta. O segundo comando é mais simples e faz o mesmo, mas ainda sem a fonte .bashrc antes.
Mehdi
@RuiFRibeiro Abuse ?? como você pode chamar uma coisa tão simples de abuso? executando um comando automaticamente após o logon em uma máquina remota com ssh, é tão simples quanto isso. Qualquer ferramenta externa que seria implantado para tal uma tarefa ridiculamente pequeno seria um exagero
Mehdi
1
Apenas uma figura de linguagem, não foi planejada para ser usada em um termo mais amplo. Use-os quando precisar, no entanto, usá-los não é tão pacífico quanto parece. No entanto, para futuras referências, dê uma olhada no Ansible, você ficaria surpreso com o quão leve ele é realmente. Frequentemente também corro comandos via ssh.
Rui F Ribeiro

Respostas:

9

O problema é que você está tentando executar um alias em um shell não interativo. Quando você executa ssh user@computer command, commandé executado de forma não interativa.

Os shells não interativos não lêem pseudônimos (do man bash):

Os aliases não são expandidos quando o shell não é interativo, a menos que a opção de shell expand_aliases seja definida usando shopt (consulte a descrição do shopt em SHELL BUILTIN COMMANDS abaixo).

Funciona se você executá-lo novamente manualmente, porque o bashcomando final inicia um shell interativo para que seus aliases estejam agora disponíveis.

Como alternativa, você pode iniciar um shell interativo ( bash -i) em vez de um simples shell de login ( bash -l) na máquina remota para executar seu alias:

ssh user@remote_computer -t 'bash -ic "my_alias;bash"'

Esta parece ser uma abordagem muito complicada. Você não explicou por que exatamente precisa fazer isso, mas considere estas alternativas:

  1. Basta iniciar um shell interativo de login normal na máquina remota e execute o comando manualmente:

    user@local $ ssh user@remote
    user@remote $ my_alias
  2. Se você sempre deseja que o alias seja executado quando você se conecta a este computador, edite o ~/.profile(ou ~/.bash_profile, se houver) do computador remoto e adicione esta linha no final:

    my_alias

    Como ~/.profileé lido sempre que um shell de login é iniciado (portanto, toda vez que você se conecta via ssh, por exemplo), isso fará com my_aliasque seja executado sempre que você se conectar.

    Observe que, por padrão, os shells de login leem ~/.profileou ~/.bash_profileignoram ~/.bashrc. Algumas distribuições (Debian e seus derivados e Arch, por exemplo), como o Ubuntu, têm sua origem padrão ~/.profileou ~/.bash_profilearquivos, o ~/.bashrcque significa que seus aliases definidos ~/.bashrctambém estarão disponíveis em um shell de login. Isso não é verdade para todas as distribuições; portanto, você pode precisar editar ~/.profilemanualmente para obter a fonte ~/.bashrc. Observe também que, se ~/.bash_profileexistir, ~/.profileserá ignorado pelo bash.

terdon
fonte
Então, você sugere que os aliases sejam definidos em um alias_profile e os chame de .profile ou .bash_profile?
Mehdi
@ Mehdi que dependerá do que você deseja fazer. No seu sistema Ubuntu, ~/.basyrcé lido automaticamente por ~./profile, portanto, qualquer alias definido ~/.bashrctambém estará disponível para qualquer leitura de shell ~/.profile. Tudo o que você realmente precisava fazer para que isso funcionasse era iniciar explicitamente um shell interativo ( -i).
terdon
5

Eu tive que comentar uma parte do meu .bashrc que impedia o uso de alias e adicionar um comando expand_aliases. Isso foi comentado

# If not running interactively, don't do anything
#case $- in
#    *i*) ;;
#      *) return;;
#esac

E isso foi adicionado

if [ -z "$PS1" ]; then
  shopt -s expand_aliases
fi

Então meu comando funcionou:

ssh user@remote_computer -t "my_alias;bash"
Mehdi
fonte