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?
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 .
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.
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.
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
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 ~.
Exportez simplement les variables d’environnement souhaitées au-dessus de la recherche d’un shell non interactif dans ~/.bashrc.