¿Cómo puedo cambiar automáticamente el directorio al iniciar sesión en ssh?

87

Estoy tratando de sshcambiar automáticamente a un directorio en particular cuando inicio sesión. Intenté que ese comportamiento funcionara usando las siguientes directivas en ~/.ssh/config:

Host example.net
LocalCommand "cd web"

pero cada vez que inicio sesión, veo lo siguiente:

/bin/bash: cd web: No such file or directory

aunque definitivamente hay una webcarpeta en mi directorio de inicio. Incluso el uso de una ruta absoluta da el mismo mensaje. Para ser claros, si escribo cd webdespués de iniciar sesión, llego a la carpeta correcta.

¿Que me estoy perdiendo aqui?

EDITAR:

Las diferentes combinaciones de comillas / rutas absolutas dan diferentes mensajes de error:

LocalCommand "cd web"
/bin/bash: cd web: No such file or directory

LocalCommand cd web
/bin/bash: line 0: cd: web: No such file or directory

LocalCommand cd /home/gareth/web
/bin/bash: line 0: cd: /home/gareth/web: Input/output error

Esto me hace pensar que las citas no deberían estar allí y que hay otro error.

Gareth
fuente
99
LocalCommand se ejecuta en su sistema local, no en el sistema remoto.
Steve Kehlet
Vea aquí superuser.com/a/124110/47962
Nakilon

Respuestas:

25

cd es un shell incorporado. LocalCommand se ejecuta como:

/bin/sh -c <localcommand>

Lo que estás buscando hacer realmente no se puede lograr a través de SSH; necesita modificar el shell de alguna manera, por ejemplo, a través de bashrc / bash_profile.

<Edición casi una década después ...>

LocalCommandno es lo que quieres, de todos modos. Eso se ejecuta en su máquina. Que desea RemoteCommand. Algo como esto funcionó para mí:

Host example.net
  RemoteCommand cd / && exec bash --login
  RequestTTY yes
BMDan
fuente
1
Sí, solo quería mencionar a lo mismo. En su lugar, puede colocar el cdcomando en ~/.bashrcel servidor remoto.
vdboor
Eso es molesto. Como mencioné en otro comentario, el servidor tiene varios nombres de host y quería tener un comportamiento diferente según el que se usara. Supongo que no es posible determinar cuál se utilizó desde .bashrc.
Gareth
Es posible, probablemente no sea aconsejable. Algo así como reemplazar ssh con un pequeño script de shell o alias que pasa el nombre del host como una variable a exportar (a la "ssh -t user @ host 'export connhostname = host; bash --login'"). Pero estás empezando a entrar en un territorio muy extraño, de hecho. Quizás una mejor pregunta es, ¿POR QUÉ quieres este comportamiento?
BMDan
No es realmente tan importante para ser honesto. Estoy en una situación en la que la gran mayoría de las veces que inicio sesión en este servidor me dirijo directamente a uno de los dos directorios (según el host que esté usando)
Gareth,
77

Esto funciona:

ssh server -t "cd /my/remote/directory; bash --login"

Para crear un directorio si no existe:

ssh server -t "mkdir -p newfolder; cd ~/newfolder; pwd; bash --login"

Si no agrega bashal final de la ruta, salga después de que se cdejecute el comando. Y si no agrega, --loginentonces su ~/.profileno es de origen.

Vladislav Lezhnev
fuente
Esto me termina en la ubicación correcta, con un indicador de bash. ¡Perfecto!
Peter Ehrlich
Esto también funciona para mí, pero si trato de usarlo con ssh jump-host, no funciona. Recibo un mensaje de conexión cerrada.
Riccardo el
43
  1. Inicia sesión en tu casilla
  2. Editar ~/.bash_profile
  3. Al final del archivo agregue cd /path/to/your/destination
  4. Guárdalo y sal
  5. Salir de la caja
  6. Inicie sesión nuevamente y debería aterrizar en /path/to/your/destination
sobi3ch
fuente
3
En algunas máquinas, es posible que deba agregarlas cd /path/to/your/destinationen ~/.bashrclugar de hacerlo ~/.bash_profile. El resultado debería ser el mismo.
Matthias
Esto funciona perfectamente gracias, ¿está restringido solo a mi ID de usuario o afectará también a los inicios de sesión de otros usuarios?
hard_working_ant
@BabyGroot si modifica ~/.bash_profileo ~/.bashrcsolo afectará al usuario actual.
rubenvarela
5

Solución más robusta para el caso en que necesita ssh y anular el archivo .bashrc predeterminado. Esto es útil en los casos en que el entorno del servidor remoto tiene múltiples docroots y es utilizado por múltiples usuarios.

alias ssh_myserver='ssh server_name -t "echo cd /path/to/desired/dir>/tmp/.bashrc_tmp; bash --rcfile /tmp/.bashrc_tmp"'

Más detallado:

  1. El primer comando crea un .bashrc_tmparchivo en el /tmpdirectorio del servidor remoto con un contenidocd /path/to/dir
  2. El siguiente comando se ejecuta bashcon el archivo de configuración especificado en el paso 1. Esto permite cambiar al directorio deseado y suprimir el predeterminado .bashrc.
  3. Todo este comando está envuelto como un alias, por lo que en el símbolo del sistema del cliente ssh se puede llamar comossh_myserver
Alex Skrypnyk
fuente
Creativo ... siempre que tenga permisos de escritura en / tmp
smci el
4

¿Ha habilitado esta directiva en su configuración ssh?

PermitLocalCommand yes

El valor predeterminado para eso es no, en cuyo caso su LocalCommanddirectiva sería ignorada.

Alternativamente, ¿ha intentado agregar el comando a su .bashrcarchivo?

EEAA
fuente
Esa directiva está establecida, sí (y supongo que no vería el mensaje de error que se muestra si no fuera así). El problema con el uso de .bashrc es que el servidor tiene diferentes nombres de host, y me gustaría que diferentes nombres de host se traduzcan a diferentes directorios de inicio
Gareth
A menos que cada nombre de host tenga una dirección IP diferente, el servidor no podría saber qué nombre de host solicitó. Mientras que las solicitudes HTTP proporcionan un host host: encabezado para identificar el nombre de host solicitado, las conexiones SSH no lo hacen.
Fosco
4

Así que busqué en muchos sitios web (stackoverflow, este) pero no encontré lo que quería. Terminé creando mi propio script de shell. Lo estoy pegando aquí. También puede copiarlo en un directorio en $ PATH.

#!/bin/bash
ssh -t <username@hostname> "cd ~/$1; exec \$SHELL --login"

Entonces después de esto. Hago:

connect <foldername>

Nota: es posible que deba cerrar sesión e iniciar sesión nuevamente después de cambiar la variable de ruta

ario
fuente
Prefiero esto a la sugerencia anterior porque '$ SHELL' siempre es válido, mientras que 'bash' puede no serlo. También el uso de 'exec' es un buen toque.
Dave
Un refinamiento adicional sería asegurar que 'cd' sea exitoso - "cd ~ / $ 1 && exec ... '
Dave
3

En su ~/.ssh/config:

LocalCommand echo '/home/%r/some/subdir' > /home/%r/.ssh/ssh_cd

Al final de su ~/.bashrc:

if [[ -f $HOME/.ssh/ssh_cd ]]
then
    cd $(<$HOME/.ssh/ssh_cd)
    # uncomment the line below and the file will be removed so the cd won't work
    # unless the file is regenerated since you may not want this to operate for
    # non-ssh logins or for ssh logins that you want to function differently
    # rm $HOME/.ssh/ssh_cd
fi

Intenté hacer esto usando el paso variable, incluso con una variable exportada, pero estos comandos se ejecutan en diferentes shells.

Al probar lo que estaba tratando de hacer, no recibí un error cuando utilicé la ruta absoluta sin comillas, por cierto. Agregué ; pwdal final del comando y se muestra el directorio correcto, sin embargo, el directorio en el que termino es ~. No hay cdcomandos en mis archivos de inicio de shell. He intentado poner a otra persona cd somedir; pwden ~/.ssh/rc(con el otro todavía en su lugar). El configcomando se ejecuta antes de que se emita el motd y el rccomando se emite después, pero antes de que se obtengan los archivos de inicio del shell. Entonces, de nuevo, está sucediendo en un caparazón diferente.

Prueba la técnica de pasar por archivo y avísame si te funciona.

Dennis Williamson
fuente
2

¿Lo has probado sin las comillas? Los únicos ejemplos que he visto no los tienen, por lo que con ellos podría tratarse de ejecutar cd \ web como un comando.

James L
fuente
Ok, eliminar las citas parece ayudar, pero todavía tengo errores (ver publicación editada)
Gareth
1

También puedes probar esto, con la opción -t:

ssh server -t "cd /my/remote/directory; bash"
kenorb
fuente
1

Intente usar en su RemoteCommandlugar, por ejemplo

Host myhost
  HostName IP
  User ubuntu
  IdentityFile ~/.ssh/id_rsa
  RemoteCommand cd web; $SHELL -il

RemoteCommand: Especifica un comando para ejecutar en la máquina remota después de conectarse con éxito al servidor. ( man ssh_config)

kenorb
fuente