当我使用 rsync 将文件从一台计算机复制到另一台计算机时,两端都会启动 rsync 进程。但是,在远程端,shell 初始化文件显然没有被读取,因此我无法为远程 rsync 进程设置环境变量。不幸的是,有一台我需要 rsync 的服务器,rsync 需要环境变量才能工作。我不是该服务器的管理员,因此我无法更改全局配置。我该怎么做才能为远程 rsync 进程设置环境变量?
答案1
~/.profile
ssh somecommand
与交互式 ssh 会话(或启动交互式会话的其他登录方法)不同,运行时通常不会读取。
ssh 支持发送环境变量。在 OpenSSH 中,SendEnv
使用~/.ssh/config
AcceptEnv
。但是,必须使用服务器配置,因此这对你来说可能不起作用。
OpenSSH 还允许在服务器端设置环境变量。同样,必须在服务器配置中启用此功能,此处使用指令PermitUserEnvironment
。可以在文件中设置变量~/.ssh/environment
假设您使用公钥身份验证,您还可以在~/.ssh/authorized_keys
:environment="FOO=bar"
在相关行的开头添加。
我认为,只要你使用公钥认证,有一件事总是有效的(很奇怪),那就是(滥用)使用command=
选项在authorized_keys
文件中。带有选项的密钥command
仅适用于运行指定的命令;但authorized_keys
文件中的命令运行时环境变量SSH_ORIGINAL_COMMAND
设置为用户指定的命令(交互式会话中为空)。因此,您可以在文件中使用类似以下内容~/.ssh/authorized_keys
(当然,如果您不使用此密钥进行身份验证,它将不适用):
command="export LD_LIBRARY_PATH=\"$HOME\"/lib;
if [ -n \"$SSH_ORIGINAL_COMMAND\" ]; then
eval \"$SSH_ORIGINAL_COMMAND\";
else exec \"$SHELL\"; fi" ssh-rsa …
请注意,为了便于阅读,我在上方添加了换行符,但实际上需要将其全部放在一行上。
~/bin/rsync-wrapper
另一种可能性是在服务器上编写包装脚本,例如
#!/bin/sh
. ~/.profile
exec rsync "$@"
然后传递--rsync-path='bin/rsync-wrapper'
命令rsync
行。 的参数--rsync-path
由 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