Ejecute un comando en un shell interactivo con ssh después de obtener .bashrc

11

Quiero ssh en una computadora Ubuntu remota, buscar mi .bashrcy ejecutar un comando que depende de los parámetros establecidos por eso .bashrc. Todo eso en un shell interactivo que no se cierra después de que se realiza el comando.

Lo que intenté hasta ahora es

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

o solo

ssh user@remote_computer -t "my_alias;bash"

Esto funciona para comandos generales (como lspor ejemplo) pero cuando intento ejecutar un alias definido en .bashrcaparece un error:

bash: my_alias: command not found

Pero luego, cuando lo escribo de nuevo manualmente y lo ejecuto, ¡funciona!

Entonces, ¿cómo puedo asegurarme de que la .bashrcfuente se obtiene antes de que se llame al comando?

Mehdi
fuente
La publicación es confusa. Recomiendo no abusar de ejecutar comandos como ese; sin embargo, si se invoca bash o un comando bash, diría que .bashrc debe ejecutarse. Evidentemente, existen algunas diferencias o peculiaridades al ejecutar un comando como ese, y para aplicaciones más serias, recomendaría Ansible o Puppet.
Rui F Ribeiro
Edité mi pregunta. El segundo comando es más simple y hace lo mismo, pero aún sin obtener .bashrc antes.
Mehdi
@RuiFRibeiro Abuse ?? ¿Cómo puedes llamar a una cosa tan simple abuso? ejecutar automáticamente un comando después de iniciar sesión en una máquina remota con ssh, es tan simple como eso. Cualquier herramienta externa que se implementaría para una tarea tan ridículamente pequeña sería una exageración
Mehdi
1
Solo una forma de hablar, no estaba destinado a ser utilizado en un término más amplio. Úselos cuando lo necesite, sin embargo, usarlos no es tan pacífico como parece. Sin embargo, para futuras referencias, eche un vistazo a Ansible, se sorprenderá de lo liviano que es en realidad. A menudo también ejecuto comandos a través de ssh.
Rui F Ribeiro

Respuestas:

9

El problema es que está intentando ejecutar un alias en un shell no interactivo. Cuando ejecuta ssh user@computer command, commandse ejecuta de forma no interactiva.

Los shells no interactivos no leen alias (de man bash):

Los alias no se expanden cuando el shell no es interactivo, a menos que la opción del shell expand_aliases se configure usando shopt (consulte la descripción de shopt en SHELL BUILTIN COMMANDS a continuación).

Funciona si lo ejecuta de nuevo manualmente porque el bashcomando final inicia un shell interactivo para que sus alias estén ahora disponibles.

Como alternativa, puede iniciar un shell interactivo ( bash -i) en lugar de un simple shell de inicio de sesión ( bash -l) en la máquina remota para ejecutar su alias:

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

Sin embargo, este parece un enfoque muy complicado. No ha explicado por qué exactamente necesita hacer esto, pero considere estas alternativas:

  1. Simplemente inicie un shell interactivo de inicio de sesión normal en la máquina remota y ejecute el comando manualmente:

    user@local $ ssh user@remote
    user@remote $ my_alias
    
  2. Si siempre desea que se ejecute ese alias cuando se conecta a esta computadora, edite el ~/.profile(o ~/.bash_profile, si está presente) de la computadora remota y agregue esta línea al final:

    my_alias

    Debido a que ~/.profilese lee cada vez que se inicia un shell de inicio de sesión ( sshpor ejemplo , cada vez que se conecta , por ejemplo), eso hará my_aliasque se ejecute cada vez que se conecte.

    Tenga en cuenta que, de forma predeterminada, los shells de inicio de sesión leen ~/.profileo ~/.bash_profileignoran ~/.bashrc. Algunas distribuciones (Debian y sus derivados y Arch, por ejemplo) distribuciones como Ubuntu tienen su fuente predeterminada ~/.profileo de ~/.bash_profilearchivos, lo ~/.bashrcque significa que sus alias definidos ~/.bashrctambién estarán disponibles en un shell de inicio de sesión. Esto no es cierto para todas las distribuciones, por lo que es posible que tenga que editar su ~/.profilemanual para tener su fuente ~/.bashrc. También tenga en cuenta que si ~/.bash_profileexiste, ~/.profileserá ignorado por bash.

terdon
fuente
Entonces, ¿sugeriría tener los alias definidos en un alias_profile y llamarlos desde .profile o .bash_profile?
Mehdi
@Mehdi que dependerá de lo que quieras hacer. En su sistema Ubuntu, ~/.basyrcse lee automáticamente ~./profile, por lo que cualquier alias definido en ~/.bashrctambién estará disponible para cualquier lectura de shells ~/.profile. Todo lo que realmente necesitaba hacer para que esto funcionara era iniciar explícitamente un shell interactivo ( -i).
terdon
5

Tuve que comentar una parte de mi .bashrc que impedía el uso de alias y agregar un comando expand_aliases. Esto fue comentado

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

Y esto fue agregado

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

Entonces mi comando funcionó:

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