Como posso alterar automaticamente o diretório no login ssh?


87

Estou tentando sshmudar automaticamente para um diretório específico ao fazer o login. Tentei fazer esse comportamento funcionar usando as seguintes diretivas ~/.ssh/config:

Host example.net
LocalCommand "cd web"

mas sempre que faço login, vejo o seguinte:

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

embora haja definitivamente uma webpasta no meu diretório pessoal. Mesmo usando um caminho absoluto, dá a mesma mensagem. Para ficar claro, se eu digitar cd webapós o login, chego à pasta correta.

O que estou perdendo aqui?

EDITAR:

Diferentes combinações de aspas / caminhos absolutos fornecem diferentes mensagens de erro:

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

Isso me faz pensar que as aspas não deveriam estar lá e que há outro erro acontecendo.


9
LocalCommand é executado no seu sistema local, não no sistema remoto.
Steve Kehlet

Respostas:


25

cd é um shell embutido. LocalCommand é executado como:

/bin/sh -c <localcommand>

O que você está procurando fazer não pode realmente ser realizado via SSH; você precisa modificar o shell de alguma forma, por exemplo, via bashrc / bash_profile.

<Editando quase uma década depois ...>

LocalCommandnão é o que você quer, de qualquer maneira. Isso é executado em sua máquina. Você quer RemoteCommand. Algo assim funcionou para mim:

Host example.net
  RemoteCommand cd / && exec bash --login
  RequestTTY yes

1
Sim, só queria mencionar o mesmo. Você pode colocar o cdcomando no ~/.bashrcservidor remoto.
vdboor

Isso é irritante. Como mencionei em outro comentário, o servidor possui vários nomes de host e eu queria ter um comportamento diferente com base no qual foi usado. Eu acho que não é possível determinar qual foi usado no .bashrc?
Gareth

É possível, mas provavelmente não é aconselhável. Algo como substituir ssh por um pequeno script de shell ou alias que passa o nome do host como uma variável a ser exportada (a la "ssh -t usuário @ host 'export connhostname = host; bash --login'"). Mas você está começando a entrar em um território muito estranho, de fato. Talvez uma pergunta melhor seja: POR QUE você quer esse comportamento?
BMDan

Não é realmente grande coisa para ser honesto. Eu sou apenas na situação em que a grande maioria do tempo eu entrar neste servidor eu ir direto para um dos dois diretórios (dependendo de qual host que estou usando)
Gareth

77

Isso funciona:

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

Para criar um diretório se ele não existir:

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

Se você não adicionar bashno final do caminho, sairá após a cdexecução do comando. E se você não adicionar --login, ~/.profilenão será fornecido.


Isso termina no local correto, com um prompt do bash. perfeito!
Peter Ehrlich

Isso funciona para mim também, mas se eu tentar usá-lo com o ssh jump-host, não funcionará. Recebo uma mensagem de conexão encerrada.
Riccardo

43
  1. Entre na sua caixa
  2. Editar ~/.bash_profile
  3. No final do arquivo, adicione cd /path/to/your/destination
  4. Salve e saia
  5. Sair da caixa
  6. Faça login novamente e você deve pousar /path/to/your/destination

3
Em algumas máquinas, pode ser necessário anexar cd /path/to/your/destinationa em ~/.bashrcvez de a ~/.bash_profile. O resultado deve ser o mesmo.
Matthias

Isso funciona perfeitamente graças - é restrito apenas ao meu ID de usuário ou afetará também os logins de outros usuários?
hard_working_ant

@BabyGroot se você modificar ~/.bash_profileou ~/.bashrcisso afetará apenas o usuário atual.
rubenvarela

5

Solução mais robusta para o caso em que você precisa ssh e substituir o arquivo .bashrc padrão. Isso é útil nos casos em que o ambiente do servidor remoto possui várias docroots e é usado por vários usuários.

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

Mais detalhado:

  1. O primeiro comando cria um .bashrc_tmparquivo no /tmpdiretório no servidor remoto com um conteúdocd /path/to/dir
  2. O próximo comando é executado bashcom o arquivo de configuração especificado na etapa 1. Isso permite alternar para o diretório desejado e suprimir o padrão .bashrc.
  3. Todo esse comando é agrupado como um aliasprompt de comando do cliente ssh, e pode ser chamado comossh_myserver

Criativa ... contanto que você tem perms gravação para / tmp
SMCI

4

Você ativou esta diretiva em sua configuração ssh?

PermitLocalCommand yes

O padrão é que no, nesse caso, sua LocalCommanddiretiva seria ignorada.

Como alternativa, você tentou adicionar o comando ao seu .bashrcarquivo?


Essa diretiva está definida, sim (e presumo que não veria a mensagem de erro mostrada se não fosse). O problema com o uso .bashrc é que o servidor tem diferentes nomes de host, e eu gostaria diferentes nomes de host para traduzir para diferentes diretórios de partida
Gareth

A menos que cada nome de host tenha um endereço IP diferente, o servidor não terá como saber qual nome de host você solicitou. Enquanto as solicitações HTTP fornecem um cabeçalho Host: amigável para identificar o nome do host solicitado, as conexões SSH não.
Fosco

4

Pesquisei muitos sites (stackoverflow, este), mas não encontrei o que queria. Acabei criando meu próprio script de shell. Eu estou colando aqui. Você também pode copiar um diretório no diretório $ PATH.

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

Então depois disso. Eu faço:

connect <foldername>

Nota: Pode ser necessário sair e efetuar login novamente após alterar a variável de caminho


Prefiro isso à sugestão anterior, porque '$ SHELL' é sempre válido, enquanto 'bash' pode não ser. Além disso, o uso de 'exec' é um toque agradável.
Dave

Um refinamento adicional iria ser garantir 'cd' é bem sucedida - "cd ~ / $ 1 && exec ...'
Dave

3

No seu ~/.ssh/config:

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

No final do seu ~/.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

Tentei fazer isso usando passagem de variável, inclusive com uma variável exportada, mas esses comandos são executados em diferentes shells.

Ao testar o que você estava tentando fazer, não recebi um erro ao usar o caminho absoluto não citado. Eu adicionei ; pwdno final do comando e o diretório correto é exibido, no entanto, o diretório em que eu acabo é ~. Não há cdcomandos nos meus arquivos de inicialização do shell. Eu tentei colocar um diferente cd somedir; pwdem ~/.ssh/rc(com o outro ainda no lugar). O configcomando é executado antes do motd ser emitido e depois do rccomando, mas antes da origem dos arquivos de inicialização do shell. Então, novamente, está acontecendo em um shell diferente.

Experimente a técnica de passagem por arquivo e deixe-me saber se funciona para você.


2

Você já experimentou sem as aspas? Os únicos exemplos que eu vi não os têm, portanto, com eles, poderia estar tentando executar o cd \ web como um comando.


Ok, removendo citações parecem ajudar, mas ainda tenho erros (ver post editado)
Gareth

1

Você também pode tentar isso com a opção -t:

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

1

Tente usar RemoteCommand, por exemplo, por exemplo

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

RemoteCommand: Especifica um comando a ser executado na máquina remota após a conexão bem-sucedida ao servidor. ( man ssh_config)

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.