sh archivos de inicio sobre ssh

10

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

En mi .profiletengo esto:

ihammerhands@wreckcreations:~> cat .profile
#specific environment and startup programs
export PS1="\u@wreckcreations:\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 name@host echo $PATH
Enter passphrase for key '/home/Owner/.ssh/id_rsa':
/usr/local/bin:/bin:/usr/bin

Observe las opciones de RUTA faltantes

¿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: Parece /bin/shenlaces a bash, lo que no es sorprendente. Lo sorprendente es que mi perfil aún se ignora. ¿Alguna sugerencia?

TheLQ
fuente
1
No tengo ganas de repetir lo que está en la página de manual, así que solo mira la página de manual de bash en la sección 'INVOCACIÓN'. Está cerca de la cima y describe todo lo que necesitas saber.
camh
Puedes intentar usarlo ssh name@host -t echo $PATH.
Gert
@Gert La salida es la misma
TheLQ
@camh ¿Crees que haría esta pregunta si no hubiera revisado las páginas del manual? He leído ellos muchas veces + otros puestos, pero nunca pudo encontrar una respuesta a esta cuestión específica, ya que no estoy seguro de qué comandos etapa ssh y comandos de otros programas se ejecutan en
TheLQ
1
@TheLQ: No te conozco, así que no sé si revisarías la página del manual. Todo lo que sabía es que las respuestas estaban allí, así que en lugar de repetirlo palabra por palabra, te lo señalé. Un puntero más específico es buscar shells no interactivos ya que ese es su escenario ssh. Si algo en la página del manual no está claro, quizás pueda hacer una pregunta más específica.
camh

Respuestas:

8

Parece que vale la pena señalar que el comando que mencionas en tu pregunta

ssh name@host echo $PATH

prácticamente nunca será útil. La sustitución de la variable para $ PATH la realiza su shell local y se pasa a ssh, que ejecuta echo en el sistema remoto para imprimir el contenido de la variable de ruta, a medida que se expande 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
will@warren'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'
will@warren'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 expanda la variable.

wrosecrans
fuente
En Windows Cygwin land, las comillas simples no hacen nada en Cygwin o en el símbolo del sistema. Curiosamente, las comillas dobles hacen que la RUTA se expanda completamente a mi máquina local en Cygwin. Entonces, lo que sea que me estaba dando ssh no era mi camino, era el servidor
TheLQ
@TheLQ Las comillas simples son necesarias en un indicador de Unix (incluido Cygwin), pero no necesita comillas en un indicador de cmd.
Gilles 'SO- deja de ser malvado'
12

~/.profilesolo 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 (colocando un -como el primer carácter del argumento zeroth en la invocación del 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, ~/.profileno se leerá.

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

Ssh también admite el envío de variables de entorno. En OpenSSH, use la SendEnvdirectiva en ~/.ssh/config. Sin embargo, la variable de entorno específica debe habilitarse con una AcceptEnvdirectiva 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 esté utilizando la autenticación de clave pública es (ab) usar la command=opción en el authorized_keysarchivo . Una tecla con una commandopción es buena solo para ejecutar el comando especificado; pero el comando en el authorized_keysarchivo se ejecuta con la variable de entorno SSH_ORIGINAL_COMMANDestablecida en el comando que especificó el usuario. Esta variable está vacía si el usuario no especificó un comando y, por lo tanto, esperaba un shell interactivo. Por lo tanto, puede usar algo como esto ~/.ssh/authorized_keys(por supuesto, no se aplicará si no usa esta clave para autenticar):

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##*/}" "$@"

Luego haga enlaces simbólicos a este script llamado rsync, unisonetc. Pase --rsync-path='bin/rsync'la rsynclínea de comando, 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 usarlo --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 lee ~/.bashrccuando 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
Gilles 'SO- deja de ser malvado'
fuente
¿Qué pasa con los comandos que otros comandos ejecutan? En este caso serían ganchos mercuriales. Mercurial necesita estar en el camino para que el gancho piense siquiera en trabajar
TheLQ
Use cualquiera de las técnicas que indiqué para que su perfil se ejecute en comandos ssh no interactivos. Uno de ellos ( command=en authorized_keys) funciona de forma transparente. Otros requieren un shell u opciones específicas en la configuración del servidor ssh. El equivalente mercurial de --rsync-pathes --remotecmd.
Gilles 'SO- deja de ser malvado'
Podría ser útil para algunos de incluir la misma llena command=de comandos como en su posterior superuser.com/a/207262/137762
mforbes
1

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

Alexander Pogrebnyak
fuente
0

Me quedo sin tiempo para probar esto, pero mirando las páginas del manual que 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 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).

kasterma
fuente
Incluso si pudiera hacer que SSH funcione al indicar explícitamente algunas variables de entorno en el entorno, todavía no ayudará a solucionar que mi perfil se ejecute cuando otros programas invocan comandos
TheLQ
En su ejemplo, todo lo que está haciendo es establecer variables de entorno, ¿qué más quiere hacer?
kasterma
0

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

Actualizar

Lo sentimos, no he visto que se trata 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 cerca posible, a la vez que se ajusta al estándar POSIX®. Los archivos de perfil leídos son / etc / profile y ~ / .profile, si se trata de 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 iniciar!).

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, a pesar de que su shell se inicia así?

Fuente


fuente
He buscado, pero como he dicho camh No sé qué comandos etapa ssh y otros comandos de programa se ejecutan en la que he leído las páginas de manual y otras guías ya muchas veces.
TheLQ