背景

背景

我想运行远程 ssh 命令并让它们始终加载服务器端默认启动文件。我正在寻找一个解决方案才不是要求:

  • 由 root 配置
  • 每次向命令添加额外的样板
  • 跨多个文件复制环境变量

我是不是希望将本地环境变量传输到远程 shell。我想使用普通ssh <host> <command>语法运行远程命令并使用远程登录会话将获得相同的环境

背景

为了简单起见,下面假设bash使用

默认情况下,远程 ssh 命令启动非交互式、非登录 shell。引用手册页:

如果命令指定后,它会在远程主机上执行,而不是在登录 shell 上执行。

您可以通过运行以下命令在 shell 上更明确地看到这一点:

# the lack of 'i' indicates non-interactive
$ ssh localhost 'echo $-'
hBc 

$ ssh localhost 'shopt login_shell'
login_shell     off

但是,如果您的远程命令需要设置某些环境变量怎么办?作为非交互式、非登录 shell 意味着两者都不 .bash_profile.bashrc不会被采购。

这是有问题的,例如,如果您使用类似的工具珀尔布鲁或者虚拟环境并希望在远程命令中使用您的自定义解释器:

$ which perl
/home/calid/perl5/perlbrew/perls/perl-5.20.1/bin/perl

$ ssh localhost 'which perl'
/usr/bin/perl

不满足上述要求的解决方案

在远程命令中显式调用登录 shell

$ ssh localhost 'bash --login -c "which perl"'

每次都需要额外的样板

在命令之前明确获取您的配置文件

$ ssh localhost 'source ~/.bash_profile && which perl'

每次都需要额外的样板

设置环境变量~/.ssh/environment

需要 root 才能在服务器上启用此功能

重复服务器启动文件中已设置的环境变量

设置ENVBASH_ENV

不起作用:.bash_profile并且.bashrc没有来源

设置~/.ssh/environment有效,但需要 root 访问权限才能启用

在命令前面加上您需要的环境变量

每次都需要额外的样板(可能很多)

重复服务器启动文件中已设置的环境变量

相关文章

https://stackoverflow.com/questions/415403/whats-the-difference- Between-bashrc-bash-profile-and-environment

https://stackoverflow.com/questions/216202/why-does-an-ssh-remote-command-get-fewer-environment-variables-then-when-run-man#216204

通过 ssh 运行命令时未获取点文件

答案1

创建一个包装外壳函数,为您添加样板代码sshc前缀:source ~/.bash_profile

function sshc {
    local host=$1
    local cmd=$2

    ssh $host "source ~/.bash_profile && $cmd"
}

然后您可以将其用作:

$ sshc localhost 'which perl'
/home/calid/perl5/perlbrew/perls/perl-5.20.1/bin/perl

答案2

bash~/.bashrc即使在非交互式调用时也确实会读取,至少在 Debian 及其衍生ssh版本#define SSH_SOURCE_BASHRC上是这样(在我看来是一个错误功能,但在这里对您来说很方便)。

~/.bashrc所以你可以添加到远程主机的顶部:

if [ -n "$SSH_CLIENT" ] &&
   [ "$SHLVL" = 0 ] &&
   [ -n "${-##*[il]*}" ]; then
   . /etc/profile
   . ~/.bash_profile
fi

相关内容