it-swarm-es.com

sh archivos de inicio sobre ssh

Tengo algunos comandos importantes que necesito ejecutar antes de que comience cualquier sh Shell. Esto es necesario para pasar comandos SSH en el comando SSH (ssh Host somecommand) y otros programas que ejecutan comandos.

En mi .profile Tengo esto:

[email protected]:~> cat .profile
#specific environment and startup programs
export PS1="\[email protected]:\w> "
export PYTHONPATH=~/python/lib/python2.4/site-packages
export PATH=$PATH:~/bin:~/python/bin

Sin embargo, esto falla:

W:\programming\wreckcreations-site\test-hg>ssh [email protected] echo $PATH
Enter passphrase for key '/home/Owner/.ssh/id_rsa':
/usr/local/bin:/bin:/usr/bin

Observe las opciones PATH que faltan

¿Cuál es el nombre propio del perfil sh? Nota: No tengo acceso de root y no quiero que esto se aplique a otros usuarios. Hay otra manera de hacer esto?


EDITAR: Aparece /bin/sh enlaza con bash, lo cual no es sorprendente. Lo sorprendente es que todavía se ignora mi perfil. ¿Alguna sugerencia?

10
TheLQ

Vale la pena señalar que el comando que menciona en su pregunta

ssh [email protected] echo $PATH

prácticamente nunca será útil. La sustitución de la variable por $ PATH la realiza su Shell local y la pasa a ssh, que ejecuta echo en el sistema remoto para imprimir el contenido de la variable de ruta, a medida que se expandió en su sistema local. Aquí hay un ejemplo de mí haciendo algo similar entre mi Mac y una máquina Linux en mi red:

LibMBP:~ will$ echo $PATH
/opt/local/bin:/opt/local/sbin:/Users/will/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/texbin:/usr/X11/bin
LibMBP:~ will$ ssh warren echo $PATH
[email protected]'s password: 
/opt/local/bin:/opt/local/sbin:/Users/will/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/texbin:/usr/X11/bin
LibMBP:~ will$ ssh warren 'echo $PATH'
[email protected]'s password: 
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
LibMBP:~ will$ 

Tenga en cuenta cómo necesitaba usar comillas para evitar que mi Shell local expandiera la variable.

8
wrosecrans

~/.profile solo se ejecuta mediante shells de inicio de sesión. El programa que llama al Shell decide si el Shell será un Shell de inicio de sesión (poniendo un - como el primer carácter del argumento cero en la invocación de Shell). Por lo general, no se ejecuta cuando inicia sesión para ejecutar un comando específico.

OpenSSH en particular invoca un Shell de inicio de sesión solo si no especifica un comando. Entonces, si especifica un comando, ~/.profile no se leerá.

OpenSSH permite configurar variables de entorno en el lado del servidor. Esto debe estar habilitado en la configuración del servidor , con la directiva PermitUserEnvironment. Las variables se pueden configurar en el archivo ~/.ssh/environment . Suponiendo que utiliza la autenticación de clave pública, también puede establecer variables por clave en ~/.ssh/authorized_keys : agregar environment="FOO=bar" al principio de la línea correspondiente.

Ssh también admite el envío de variables de entorno. En OpenSSH, use la directiva SendEnv en ~/.ssh/config . Sin embargo, la variable de entorno específica debe estar habilitada con una directiva AcceptEnv en la configuración del servidor, por lo que es posible que esto no funcione para usted.

Una cosa que creo que siempre funciona (por extraño que parezca) siempre que utilice la autenticación de clave pública es (ab) usar el command= opción en la authorized_keys archivo . Una clave con una opción command es buena solo para ejecutar el comando especificado; pero el comando en el authorized_keys el archivo se ejecuta con la variable de entorno SSH_ORIGINAL_COMMAND establecido en el comando especificado por el usuario. Esta variable está vacía si el usuario no especificó un comando y, por lo tanto, esperaba un Shell interactivo. Entonces puedes usar algo como esto en ~/.ssh/authorized_keys (por supuesto, no se aplicará si no usa esta clave para autenticarse):

command=". ~/.profile; if [ -n \"$SSH_ORIGINAL_COMMAND\" ]; then eval \"$SSH_ORIGINAL_COMMAND\"; else exec \"$Shell\"; fi" ssh-rsa …

Otra posibilidad es escribir scripts de envoltura en el servidor. Algo como lo siguiente en ~/bin/ssh-wrapper:

#!/bin/sh
. ~/.profile
exec "${0##*/}" "[email protected]"

Luego haga enlaces simbólicos a este script llamado rsync, unison, etc. Pase --rsync-path='bin/rsync' en la línea de comando rsync, y así sucesivamente para otros programas. Alternativamente, algunos comandos le permiten especificar un fragmento de Shell completo para que se ejecute de forma remota, lo que le permite hacer que el comando sea autónomo: por ejemplo, con rsync, puede usar --rsync-path='. ~/.profile; rsync'.

Hay otra vía que depende de que su Shell de inicio de sesión sea bash o zsh. Bash siempre dice ~/.bashrc cuando es invocado por rshd o sshd, incluso si no es interactivo (pero no si se llama como sh). Zsh siempre lee ~/.zshenv.

## ~/.bashrc
if [[ $- != *i* ]]; then
  # Either .bashrc was sourced explicitly, or this is an rsh/ssh session.
  . ~/.profile
fi

## ~/.zshenv
if [[ $(ps -p $PPID -o comm=) = [rs]shd && $- != *l* ]]; then
  # Not a login Shell, but this is an rsh/ssh session
  . ~/.profile
fi

Por lo general, al iniciar sesión, bash lee los comandos de:

~/.bash_profile
~/.bashrc

Desde la página de manual de bash:

~/.bash_profile
El archivo de inicialización personal, ejecutado para shells de inicio de sesión

~/.bashrc
El archivo de inicio individual por shell interactivo

1

Me quedo sin tiempo para probar esto, pero mirando las páginas de manual encontré:

man bash: cuando bash se inicia de forma no interactiva, para ejecutar un script de Shell, por ejemplo, busca la variable BASH_ENV en el entorno, expande su valor si aparece allí y usa el valor expandido como el nombre de un archivo para leer y ejecutar. Bash se comporta como si se ejecutara el siguiente comando: if [-n "$ BASH_ENV"]; luego . "$ BASH_ENV"; fi pero el valor de la variable PATH no se usa para buscar el nombre del archivo.

man ssh: ~/.ssh/environment Contiene definiciones adicionales para las variables de entorno; ver MEDIO AMBIENTE, arriba.

La combinación sugiere cómo puede hacer que ssh ejecute su .profile

Desafortunadamente, mi servidor tiene PermitUserEnvironment con el valor predeterminado de no, lo que hace que esto no funcione para mí (y como dije, no tengo tiempo para jugar más con él).

0
kasterma

(eliminado ... solo puede tener un hipervínculo como nuevo usuario ~)

Actualizar

Lo siento, no he visto que se trate de una sesión no interactiva, a la que no se aplica el enlace anterior.

Cuando Bash se inicia en el modo de compatibilidad SH, intenta imitar el comportamiento de inicio de las versiones históricas de sh lo más fielmente posible, al mismo tiempo que cumple con el estándar POSIX®. Los archivos de perfil leídos son/etc/profile y ~/.profile, si es un Shell de inicio de sesión.

Si no es un Shell de inicio de sesión, se evalúa la variable de entorno ENV y el nombre de archivo resultante se toma como nombre del archivo de inicio.

Después de leer los archivos de inicio, Bash ingresa al modo de compatibilidad POSIX (r) (¡para ejecutar, no para comenzar!).

Bash comienza en modo de compatibilidad sh cuando:

  • el nombre de archivo base en argv [0] es sh (:!: Atención queridos usuarios de Linux súper inteligentes .../bin/sh puede estar vinculado a/bin/bash, pero eso no significa que actúe como/bin/bash :! :)

Entonces, la pregunta es, ¿por qué no lo ejecuta, aunque su Shell se inicie así?.

Fuente

0
phant0m