~/.profile
viene eseguito solo dalle shell di login. Il programma che chiama la shell decide se la shell sarà una shell di login (inserendo a -
come primo carattere dell'argomento zeroth nell'invocazione della shell). In genere non viene eseguito quando si accede per eseguire un comando specifico.
In particolare OpenSSH invoca una shell di accesso solo se non si specifica un comando. Quindi, se si specifica un comando, ~/.profile
non verrà letto.
OpenSSH consente di impostare le variabili di ambiente sul lato server. Questo deve essere abilitato nella configurazione del server , con la PermitUserEnvironment
direttiva. Le variabili possono essere impostate nel file ~/.ssh/environment
. Supponendo che tu utilizzi l'autenticazione con chiave pubblica, puoi anche impostare variabili per chiave in ~/.ssh/authorized_keys
: aggiungi environment="FOO=bar"
all'inizio della riga pertinente.
Ssh supporta anche l'invio di variabili d'ambiente. In OpenSSH, usa la SendEnv
direttiva in ~/.ssh/config
. Tuttavia, la variabile di ambiente specifica deve essere abilitata con una AcceptEnv
direttiva nella configurazione del server, quindi potrebbe non funzionare per te.
Una cosa che penso funzioni sempre (abbastanza stranamente) fintanto che stai usando l'autenticazione con chiave pubblica è (ab) usare l' command=
opzione nel authorized_keys
file . Una chiave con command
un'opzione è valida solo per l'esecuzione del comando specificato; ma il comando nel authorized_keys
file viene eseguito con la variabile di ambiente SSH_ORIGINAL_COMMAND
impostata sul comando specificato dall'utente. Questa variabile è vuota se l'utente non ha specificato un comando e quindi si aspettava una shell interattiva. Quindi puoi usare qualcosa del genere in ~/.ssh/authorized_keys
(ovviamente, non si applicherà se non usi questa chiave per autenticarti):
command=". ~/.profile; if [ -n \"$SSH_ORIGINAL_COMMAND\" ]; then eval \"$SSH_ORIGINAL_COMMAND\"; else exec \"$SHELL\"; fi" ssh-rsa …
Un'altra possibilità è scrivere script di un wrapper sul server. Qualcosa di simile al seguente in ~/bin/ssh-wrapper
:
#!/bin/sh
. ~/.profile
exec "${0##*/}" "$@"
Quindi crea collegamenti simbolici a questo script chiamato rsync
, unison
ecc. Passa --rsync-path='bin/rsync'
dalla rsync
riga di comando e così via per altri programmi. In alternativa, alcuni comandi consentono di specificare un intero frammento di shell da eseguire in remoto, il che consente di rendere autonomo il comando: ad esempio, con rsync, è possibile utilizzare --rsync-path='. ~/.profile; rsync'
.
C'è un'altra strada che dipende dal fatto che la shell di accesso sia bash o zsh. Bash legge sempre ~/.bashrc
quando viene invocato da rshd o sshd, anche se non è interattivo (ma non se si chiama come sh
). Zsh legge sempre ~/.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