Exécutez une commande dans un shell interactif avec ssh après avoir sourcing .bashrc

11

Je veux ssh dans un ordinateur Ubuntu distant, source mon .bashrcet exécuter une commande qui dépend des paramètres définis par cela .bashrc. Tout cela dans un shell interactif qui ne se ferme pas une fois la commande terminée.

Ce que j'ai essayé jusqu'à présent, c'est

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

ou juste

ssh user@remote_computer -t "my_alias;bash"

Cela fonctionne pour les commandes générales (comme lspar exemple) mais lorsque j'essaie d'exécuter un alias défini dans .bashrcj'obtiens une erreur:

bash: my_alias: command not found

Mais quand je l'écris à nouveau manuellement et l'exécute, cela fonctionne!

Alors, comment puis-je m'assurer que le .bashrcest originaire avant l'appel de la commande?

Mehdi
la source
Le message est déroutant. Je recommande de ne pas abuser des commandes en cours d'exécution comme ça; néanmoins, si bash ou une commande bash est invoquée, je dirais que .bashrc est censé s'exécuter. Il y a évidemment des différences ou des particularités à exécuter une commande comme ça, et pour des applications plus sérieuses, je recommanderais Ansible ou marionnette.
Rui F Ribeiro
J'ai édité ma question. La deuxième commande est plus simple et fait de même, mais toujours sans sourcing .bashrc auparavant.
Mehdi
@RuiFRibeiro Abuse ?? comment pouvez-vous appeler une chose aussi simple un abus ?? exécuter automatiquement une commande après s'être connecté à une machine distante avec ssh, c'est aussi simple que cela. Tout outil externe qui serait déployé pour une tâche aussi ridiculement petite serait une surpuissance
Mehdi
1
Un simple chiffre de parole n'était pas destiné à être utilisé dans un sens plus large. Utilisez-les lorsque vous en avez besoin, mais leur utilisation n'est pas aussi paisible qu'il y paraît. Néanmoins, pour de futures références, jetez un œil à Ansible, vous seriez étonné de sa légèreté. Je lance souvent des commandes via ssh.
Rui F Ribeiro

Réponses:

9

Le problème est que vous essayez d'exécuter un alias dans un shell non interactif. Lorsque vous exécutez ssh user@computer command, commands'exécute de manière non interactive.

Les shells non interactifs ne lisent pas les alias (de man bash):

Les alias ne sont pas développés lorsque le shell n'est pas interactif, sauf si l'option de shell expand_aliases est définie à l'aide de shopt (voir la description de shopt sous SHELL BUILTIN COMMANDS ci-dessous).

Cela fonctionne si vous l'exécutez à nouveau manuellement car la bashcommande finale démarre un shell interactif afin que vos alias soient désormais disponibles.

Comme alternative, vous pouvez lancer un shell interactif ( bash -i) au lieu d'un simple shell de connexion ( bash -l) sur la machine distante pour exécuter votre alias:

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

Cela semble cependant une approche très compliquée. Vous n'avez pas expliqué pourquoi vous devez exactement le faire, mais envisagez ces alternatives:

  1. Il suffit de démarrer un shell interactif de connexion normale sur la machine distante et d'exécuter la commande manuellement:

    user@local $ ssh user@remote
    user@remote $ my_alias
    
  2. Si vous souhaitez toujours que cet alias soit exécuté lorsque vous vous connectez à cet ordinateur, modifiez ~/.profile(ou ~/.bash_profile, s'il est présent) de l'ordinateur distant et ajoutez cette ligne à la fin:

    my_alias

    Parce que ~/.profileest lu chaque fois qu'un shell de connexion est démarré (donc, à chaque connexion via ssh, par exemple), cela provoquera my_aliasson exécution à chaque connexion.

    Notez que par défaut, les shells de connexion lisent ~/.profileou ~/.bash_profileignorent ~/.bashrc. Certaines distributions (Debian et ses dérivés et Arch, par exemple) comme Ubuntu ont leur source par défaut ~/.profileou ~/.bash_profilefichiers, ~/.bashrcce qui signifie que vos alias définis dans ~/.bashrcseront également disponibles dans un shell de connexion. Ce n'est pas le cas pour toutes les distributions, vous devrez donc peut-être modifier ~/.profilemanuellement votre source ~/.bashrc. Notez également que s'il ~/.bash_profileexiste, ~/.profileil sera ignoré par bash.

terdon
la source
Donc, suggéreriez-vous de définir les alias dans un alias_profile et de les appeler à partir de .profile ou .bash_profile?
Mehdi
@Mehdi qui dépendra de ce que vous voulez faire. Sur votre système Ubuntu, ~/.basyrcest automatiquement lu par ~./profile, donc tous les alias définis dans ~/.bashrcseront également disponibles pour tous les shells en lecture ~/.profile. Tout ce que vous aviez vraiment besoin de faire pour que cela fonctionne était de démarrer explicitement un shell interactif ( -i).
terdon
5

J'ai dû commenter une partie de mon .bashrc qui empêchait l'utilisation d'alias et ajouter une commande expand_aliases. Cela a été commenté

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

Et cela a été ajouté

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

Ensuite, ma commande a fonctionné:

ssh user@remote_computer -t "my_alias;bash"
Mehdi
la source