~/.profile
仅由登录shell执行。调用该shell的程序确定该shell是否将是登录shell(通过-
在shell调用上放置第0个参数的第一个字符作为a )。登录以执行特定命令时,通常不会执行该命令。
仅当您不指定命令时,OpenSSH才会调用登录Shell。因此,如果您指定命令,~/.profile
将不会被读取。
OpenSSH允许在服务器端设置环境变量。必须在服务器配置中使用PermitUserEnvironment
指令启用此功能。可以在文件中设置变量~/.ssh/environment
。假设您使用公共密钥身份验证,还可以在相关行的开头的~/.ssh/authorized_keys
:add environment="FOO=bar"
中设置每个密钥的变量。
Ssh还支持发送环境变量。在OpenSSH中,使用中的SendEnv
指令~/.ssh/config
。但是,必须AcceptEnv
在服务器配置中使用指令启用特定的环境变量,因此这可能对您不可行。
只要您使用公钥身份验证,我认为一件事总是可以做的(很奇怪)是(滥用)文件中的command=
选项authorized_keys
。带command
选项的键仅适用于运行指定的命令。但是authorized_keys
文件中的命令在环境变量SSH_ORIGINAL_COMMAND
设置为用户指定的命令的情况下运行。如果用户未指定命令,因此需要交互式外壳程序,则此变量为空。因此,您可以在其中使用类似的内容~/.ssh/authorized_keys
(当然,如果您不使用此密钥进行身份验证,那么它将不适用):
command=". ~/.profile; if [ -n \"$SSH_ORIGINAL_COMMAND\" ]; then eval \"$SSH_ORIGINAL_COMMAND\"; else exec \"$SHELL\"; fi" ssh-rsa …
另一种可能性是在服务器上编写包装器脚本。类似于以下内容~/bin/ssh-wrapper
:
#!/bin/sh
. ~/.profile
exec "${0##*/}" "$@"
然后建立指向该脚本的符号链接,称为rsync
,unison
等等--rsync-path='bin/rsync'
。在rsync
命令行上传递,以此类推。另外,有些命令允许您指定整个shell片段以远程运行,这使您可以使命令自包含:例如,对于rsync,可以使用--rsync-path='. ~/.profile; rsync'
。
还有另一种方法,这取决于您的登录shell是bash还是zsh。Bash总是~/.bashrc
在rshd或sshd调用时读取,即使它不是交互式的(但如果调用为sh
)也不是。Zsh总是读取~/.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