~/.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