web-dev-qa-db-fra.com

Pourquoi une commande distante SSH obtient-elle moins de variables d'environnement que lorsqu'elle est exécutée manuellement?

J'ai une commande qui fonctionne bien si je ssh sur une machine et l'exécute, mais échoue lorsque j'essaie de l'exécuter à l'aide d'une commande ssh distante telle que:

ssh user@IP <command>

Comparer les résultats de "env" en utilisant les deux méthodes donne des résultats dans des environnements différents. Lorsque je me connecte manuellement à la machine et exécute env, j'obtiens beaucoup plus de variables d'environnement que lorsque j'exécute:

ssh user@IP "env"

Une idée pourquoi?

221
Tom Feiner

Il existe différents types d'obus. Le shell d'exécution de la commande SSH est un shell non interactif, alors que votre shell normal est un shell de connexion ou un shell interactif. La description suit, de l'homme bash:

 Un shell de connexion est un shell dont le premier caractère de l’argument 
 Zéro est un - ou un caractère commençant par l’option --login. 
 
 Un shell interactif est un démarré sans arguments non-option 
 et sans l'option -c dont l'entrée standard 
 et l'erreur sont toutes deux connectées à des terminaux (comme déterminé 
 par isatty (3)), ou un démarré avec l'option -i. PS1 est 
 Défini et $ - inclut i si bash est interactif, permettant à un script 
 Shell ou à un fichier de démarrage de tester cet état. 
 
 Les paragraphes suivants décrivent comment bash exécute ses fichiers de démarrage 
. Si l'un des fichiers existe mais ne peut pas être lu., Bash rapporte une erreur. Les tildes sont développées dans les noms de fichiers 
 Comme décrit ci-dessous sous Développement de tilde dans la section 
 EXPANSION. 
 
 Lorsque bash est appelé en tant que shell de connexion interactif ou 
 un shell non interactif avec l'option --login, il commence par lire et exécuter les commandes du fichier/etc/profile, si ce fichier existe déjà. Après avoir lu ce fichier, il recherche 
 ~/.Bash_profile, ~/.bash_login et ~/.profile, dans cet ordre 
, Puis lit et exécute les commandes du premier 
 qui existe et est lisible. L'option --noprofile peut 
 Être utilisée lorsque le shell commence à inhiber ce comportement 
 Ior. 
 
 Lorsqu'un shell de connexion se ferme, bash lit et exécute des commandes 
 du fichier ~/.bash_logout, s'il existe. 
 
 Lorsqu'un shell interactif qui n'est pas un login est démarré, [bas.] lit et exécute des commandes. de ~/.bashrc, 
 si ce fichier existe. Cela peut être inhibé en utilisant l’option 
 --Norc. L'option de fichier --rcfile forcera bash 
 À lire et à exécuter les commandes d'un fichier au lieu de 
 ~/.Bashrc. 
 
 Lorsque bash est démarré de manière non interactive Pour exécuter un script Shell 
, par exemple, il recherche la variable BASH_ENV dans [.____] l'environnement, étend sa valeur s'il y apparaît, 
 et utilise la valeur développée comme paramètre. nom du fichier à lire 
 et à exécuter. Bash se comporte comme si la commande suivante 
 Avait été exécutée: 
 If [-n "$ BASH_ENV"]; puis . "$ BASH_ENV"; fi 
 mais la valeur de la variable PATH n'est pas utilisée pour rechercher le nom de fichier dans 
. 
 
159
Vinko Vrsalovic

Que diriez-vous de rechercher le profil avant d'exécuter la commande?

ssh user@Host "source /etc/profile; /path/script.sh"

Vous trouverez peut-être préférable de changer cela en ~/.bash_profile, ~/.bashrc, ou peu importe.

(As here (linuxquestions.org) )

112
Ian Vaughan

L'environnement shell ne se charge pas lors de l'exécution de la commande ssh à distance. Vous pouvez éditer le fichier d’environnement ssh:

vi ~/.ssh/environment

Son format est:

VAR1=VALUE1
VAR2=VALUE2

Vérifiez également la configuration de sshd pour l'option PermitUserEnvironment = yes.

83
dpedro

J'ai eu un problème similaire, mais à la fin, j'ai découvert que ~/.bashrc était tout ce dont j'avais besoin.

Cependant, dans Ubuntu, je devais commenter la ligne qui arrête le traitement de ~/.bashrc:

#If not running interactively, don't do anything
[ -z "$PS1" ] && return
60
tomaszbak

J'ai trouvé une solution facile à ce problème en ajoutant source/etc/profile en haut du fichier script.sh que j'essayais d'exécuter sur le système cible. Sur les systèmes ici, cela a provoqué la configuration des variables d'environnement nécessaires à script.sh comme si elles étaient exécutées à partir d'un shell de connexion.

Dans l'une des réponses précédentes, il a été suggéré d'utiliser ~/.bashr_profile, etc. Je n'ai pas passé beaucoup de temps là-dessus, mais le problème, c'est que si vous vous connectez à un autre utilisateur du système cible que le shell du système source à partir duquel vous vous connectez, il m'est apparu que cela entraînait l'utilisateur du système source. nom à utiliser pour le ~.

4
Chuck

Exportez simplement les variables d’environnement souhaitées au-dessus de la recherche d’un shell non interactif dans ~/.bashrc.

3
Michael MacDonald