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

StackOverflow https://stackoverflow.com/questions/216202

  •  03-07-2019
  •  | 
  •  

Question

J'ai une commande qui fonctionne correctement si je ssh sur une machine et je 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>

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

ssh user@IP "env"

Avez-vous une idée du pourquoi?

Était-ce utile?

La solution

Il existe différents types d'obus. Le shell d'exécution de 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:

       A  login  shell  is  one whose first character of argument
       zero is a -, or one started with the --login option.

       An interactive shell is  one  started  without  non-option
       arguments  and  without the -c option whose standard input
       and error are both connected to terminals  (as  determined
       by  isatty(3)), or one started with the -i option.  PS1 is
       set and $- includes i if bash is interactive,  allowing  a
       shell script or a startup file to test this state.

       The  following  paragraphs  describe how bash executes its
       startup files.  If any of the files exist  but  cannot  be
       read,  bash reports an error.  Tildes are expanded in file
       names as described below  under  Tilde  Expansion  in  the
       EXPANSION section.

       When  bash is invoked as an interactive login shell, or as
       a non-interactive shell with the --login option, it  first
       reads and executes commands from the file /etc/profile, if
       that file exists.  After reading that file, it  looks  for
       ~/.bash_profile,  ~/.bash_login,  and  ~/.profile, in that
       order, and reads and executes commands from the first  one
       that  exists  and is readable.  The --noprofile option may
       be used when the shell is started to inhibit  this  behav­
       ior.

       When a login shell exits, bash reads and executes commands
       from the file ~/.bash_logout, if it exists.

       When an interactive shell that is not  a  login  shell  is
       started,  bash reads and executes commands from ~/.bashrc,
       if that file exists.  This may be inhibited by  using  the
       --norc  option.   The --rcfile file option will force bash
       to  read  and  execute  commands  from  file  instead   of
       ~/.bashrc.

       When  bash  is  started  non-interactively, to run a shell
       script, for example, it looks for the variable BASH_ENV in
       the  environment,  expands  its value if it appears there,
       and uses the expanded value as the name of a file to  read
       and  execute.   Bash  behaves  as if the following command
       were executed:
              if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi
       but the value of the PATH variable is not used  to  search
       for the file name.

Autres conseils

Et si vous recherchiez le profil avant d'exécuter la commande?

utilisateur ssh @ hôte " source / etc / profile; /path/script.sh"

Vous trouverez peut-être mieux de changer cela en ~ / .bash_profile , ~ / .bashrc , ou peu importe.

(As ici (linuxquestions.org) )

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'avais un problème similaire, mais j'ai finalement 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: ajouter   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, les variables d’environnement nécessaires à script.sh ont été configurées comme si elles étaient exécutées à partir d’un shell de connexion.

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

Exportez simplement les variables d'environnement de votre choix au-dessus de la vérification d'un shell non interactif dans ~ / .bashrc.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top