Come posso cambiare automaticamente la directory al login ssh?


87

Sto provando a passare sshautomaticamente a una directory specifica quando eseguo l'accesso. Ho provato a far funzionare quel comportamento usando le seguenti direttive in ~/.ssh/config:

Host example.net
LocalCommand "cd web"

ma ogni volta che eseguo l'accesso, vedo quanto segue:

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

anche se c'è sicuramente una webcartella nella mia home directory. Anche usando un percorso assoluto dà lo stesso messaggio. Per essere chiari, se scrivo cd webdopo aver effettuato l'accesso ottengo la cartella giusta.

Cosa mi sto perdendo qui?

MODIFICARE:

Diverse combinazioni di virgolette / percorsi assoluti forniscono diversi messaggi di errore:

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

Questo mi fa pensare che le virgolette non dovrebbero essere lì e che sta accadendo un altro errore.


9
LocalCommand viene eseguito sul sistema locale, non sul sistema remoto.
Steve Kehlet,

Risposte:


25

cd è una shell integrata. LocalCommand viene eseguito come:

/bin/sh -c <localcommand>

Quello che stai cercando di fare non può davvero essere realizzato tramite SSH; è necessario modificare la shell in qualche modo, ad esempio tramite bashrc / bash_profile.

<Modifica quasi un decennio dopo ...>

LocalCommandnon è quello che vuoi, comunque. È eseguito sulla tua macchina. Tu vuoi RemoteCommand. Qualcosa del genere ha funzionato per me:

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

1
Sì, volevo solo menzionare lo stesso. È possibile invece inserire il cdcomando ~/.bashrcsul server remoto.
vdboor,

Questo è fastidioso. Come ho detto in un altro commento, il server ha un numero di nomi host e volevo avere un comportamento diverso in base al quale è stato utilizzato. Suppongo che non sia possibile determinare quale sia stato utilizzato da .bashrc?
Gareth,

È possibile, probabilmente non consigliabile. Qualcosa come sostituire ssh con uno script di shell piccolo o un alias che passa il nome host come variabile da esportare (a la "ssh -t user @ host 'export nomehost = host; bash --login'"). Ma stai cominciando ad entrare in un territorio molto strano, anzi. Forse una domanda migliore è: PERCHÉ vuoi questo comportamento?
BMDan,

A dire il vero non è un grosso problema. Sono solo nella situazione in cui la maggior parte delle volte che accedo a questo server mi dirigo direttamente a una delle due directory (a seconda dell'host che sto usando)
Gareth

77

Questo funziona:

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

Per creare una directory se non esiste:

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

Se non aggiungi bashalla fine del percorso, esci dopo l' cdesecuzione del comando. E se non si aggiunge --loginallora il vostro ~/.profilenon è di provenienza.


Questo mi finisce nella posizione corretta, con un prompt di bash. Perfetto!
Peter Ehrlich,

Questo funziona anche per me, ma se provo ad usarlo con ssh jump-host non funziona. Ricevo un messaggio di connessione chiusa.
Riccardo,

43
  1. Accedi al tuo box
  2. modificare ~/.bash_profile
  3. Alla fine del file aggiungere cd /path/to/your/destination
  4. Salvalo ed esci
  5. Esci dalla scatola
  6. Effettua nuovamente l'accesso e dovresti atterrare /path/to/your/destination

3
Su alcune macchine potrebbe essere necessario aggiungere cd /path/to/your/destinationa ~/.bashrcinvece di ~/.bash_profile. Il risultato dovrebbe essere lo stesso.
Matthias,

Funziona perfettamente grazie - è limitato solo al mio ID utente o influenzerà anche gli accessi di altri utenti?
hard_working_ant

@BabyGroot se si modifica ~/.bash_profileo ~/.bashrcinteresserà solo l'utente corrente.
rubenvarela,

5

Soluzione più solida per il caso in cui è necessario ssh e sovrascrivere il file .bashrc predefinito. Ciò è utile nei casi in cui l'ambiente server remoto ha più docroot e utilizzati da più utenti.

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

Più dettagliato:

  1. Il primo comando crea il .bashrc_tmpfile nella /tmpdirectory sul server remoto con un contenutocd /path/to/dir
  2. Il comando successivo viene eseguito bashcon il file di configurazione specificato nel passaggio 1. Ciò consente di passare alla directory desiderata e di sopprimere l'impostazione predefinita .bashrc.
  3. L'intero comando è racchiuso come un alias, quindi sul prompt dei comandi del client ssh può essere chiamato comessh_myserver

Creativo ... fintanto che hai scritto permessi su / tmp
smci

4

Hai abilitato questa direttiva nella tua configurazione ssh?

PermitLocalCommand yes

L'impostazione predefinita è no, nel qual caso la tua LocalCommanddirettiva verrebbe ignorata.

In alternativa, hai provato ad aggiungere il comando al tuo .bashrcfile?


Tale direttiva è impostata sì (e presumo che non visualizzerei il messaggio di errore se non lo fosse). Il problema con l'utilizzo di .bashrc è che il server ha nomi host diversi e vorrei che nomi host diversi traducessero in directory iniziali diverse
Gareth,

A meno che ogni nome host non abbia un indirizzo IP diverso, non ci sarebbe modo per il server di sapere quale nome host richiesto. Mentre le richieste HTTP forniscono un'intestazione Host: amichevole per identificare il nome host richiesto, le connessioni SSH no.
Fosco,

4

Quindi ho cercato molti siti web (stackoverflow, questo) ma non ho trovato quello che volevo. Ho finito per creare il mio script di shell. Lo sto incollando qui. Inoltre puoi copiarlo in una directory nel $ PATH.

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

Quindi dopo questo. Lo voglio:

connect <foldername>

Nota: potrebbe essere necessario disconnettersi e riconnettersi dopo aver modificato la variabile del percorso


Preferisco questo al suggerimento precedente perché '$ SHELL' è sempre valido, mentre 'bash' potrebbe non esserlo. Anche l'uso di 'exec' è un bel tocco.
Dave,

Un ulteriore perfezionamento dovrebbe essere quello di garantire che 'cd' abbia successo - "cd ~ / $ 1 && exec ... '
Dave

3

Nel tuo ~/.ssh/config:

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

Alla fine del tuo ~/.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

Ho provato a farlo usando il passaggio di variabili, anche con una variabile esportata, ma questi comandi vengono eseguiti in diverse shell.

A proposito di ciò che stavi cercando di fare, non ho ricevuto alcun errore quando ho utilizzato il percorso assoluto non quotato. Ho aggiunto ; pwdalla fine del comando e viene visualizzata la directory corretta, tuttavia la directory in cui finisco è ~. Non ci sono cdcomandi nei miei file di avvio della shell. Ho provato mettendo un diverso cd somedir; pwda ~/.ssh/rc(con l'altro ancora in posizione). Il configcomando viene eseguito prima dell'emissione del motd e successivamente del rccomando, ma prima che i file di avvio della shell vengano acquisiti. Quindi, sta succedendo in un altro guscio.

Prova la tecnica del passaggio per file e fammi sapere se funziona per te.


2

L'hai provato senza le virgolette? Gli unici esempi che ho visto non li hanno quindi con loro potrebbe essere il tentativo di eseguire cd \ web come comando.


Ok, la rimozione delle virgolette sembra aiutare ma ho ancora degli errori (vedi post modificato)
Gareth

1

Puoi anche provare questo, con l'opzione -t:

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

1

Prova ad usare RemoteCommandinvece, ad es

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

RemoteCommand: Specifica un comando da eseguire sul computer remoto dopo aver effettuato correttamente la connessione al server. ( man ssh_config)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.