我通过SSH从本地服务器在远程服务器上运行脚本。首先使用SCP复制脚本,然后在传递一些参数时调用,如下所示:
scp /path/to/script server.example.org:/another/path/
ssh server.example.org \
MYVAR1=1 \
MYVAR2=2 \
/another/path/script
这很好用,在远程服务器上,变量MYVAR1
和MYVAR2
可以使用相应的值。
问题是这些脚本处于不断发展状态,每次重命名,添加或删除变量时都需要更改SSH命令。</ p>
我正在寻找一种方法将所有本地环境变量传递给远程脚本(因为MYVAR1
和MYVAR2
实际上是本地环境变量),这将解决SSH命令维护问题。< / p>
由于MYVAR1=1 \
和MYVAR1=1 \
是env
命令输出后面的行,我尝试用实际命令替换它们,如下所示:
ssh server.example.org \
`env`
/another/path/script
这似乎适用于“简单”env
输出行(例如SHELL=/bin/bash
或LOGNAME=sysadmin
),但是我会因更多“复杂”输出行而出错(例如{{1}这会产生诸如LS_COLORS=rs=0:di=01;34:ln=01;[...]
)之类的错误。我可以通过在运行SSH命令之前取消设置与这些复杂输出行相对应的变量来解决这些错误(例如-bash: 34:ln=01: command not found
,然后unset LS_COLORS
)但是我发现这个解决方案非常可靠。< / p>
问:有人知道如何通过SSH将所有本地环境变量传递给远程脚本吗?
PS:本地环境变量不是远程计算机so I cannot use this solution上可用的环境变量。
使用解决方案更新
我最后使用ssh [...]
格式化从sed
到env
的{{1}}命令输出(并将所有行连接到1),这阻止bash解释一些输出为命令并修复我的问题。
VAR=VALUE
答案 0 :(得分:7)
我碰巧阅读了与此无关的sshd_config
手册页,找到了选项AcceptEnv
:
<强> AcceptEnv 强> 指定客户端发送的环境变量 将会 复制到会话的环境中(7)。请参阅SendEnv in ssh_config(5)用于配置客户端。注意 ENVI提取 只有协议2支持ronment传递。 变量是 由name指定,可能包含通配符 字符
*' and
?'。可以分离多个环境变量 通过 空格或分布在多个AcceptEnv指令中。 是 警告说可以使用一些环境变量 旁路 受限用户环境。出于这个原因,关心 应该 采用这个指令。默认不是 接受 任何环境变量。
也许您可以将其与AcceptEnv: *
一起使用?我没有方便的sshd盒子,但试试看!
答案 1 :(得分:2)
问题是;
标记了命令的结束。你必须逃脱它们:
尝试使用此命令:
env | sed 's/;/\\;/g'
<强>更新强>: 我测试了远程主机的命令,它使用此命令对我有用:
var1='something;using semicolons;'
ssh hostname "`env | sed 's/;/\\\\;/g' | sed 's/.*/set &\;/g'` echo \"$var1\""
我双重转义;
whit \\\\;
然后我使用其他sed替换以set name=value;
的形式输出变量。这样做可以确保在执行命令之前,在远程主机上设置每个变量的相关性。
答案 2 :(得分:2)
您应该使用set
代替env
。
来自bash手册:
如果没有选项,每个shell变量的名称和值都会以一种格式显示,可以重复用作设置或重置当前设置变量的输入。
这将解决您的所有分号和反斜杠问题。
scp /path/to/script server.example.org:/another/path/
set > environment
scp environment server.example.org:/another/path/
ssh server.example.org "source environment; /another/path/script"
如果您不想发送任何变量,可以使用以下内容过滤掉它们:
set | grep -v "DONT_NEED" > environment
您还可以在登录时更新远程系统上的~/.bash_profile
以运行环境脚本,这样您就不必显式运行环境脚本:
ssh server.example.org "/another/path/script"
答案 3 :(得分:1)
如何同时上传环境?
scp /path/to/script server.example.org:/another/path/
env > environment
scp environment server.example.org:/another/path
ssh server.example.org "source environment; /another/path/script"
答案 4 :(得分:1)
Perl救援:
#!/usr/bin/perl
use strict;
use warnings;
use Net::OpenSSH;
use Getopt::Long;
my $usage = "Usage:\n $0 --env=FOO --env=BAR ... [user\@]host command args\n\n";
my @envs;
GetOptions("env=s" => \@envs)
or die $usage;
my $host = shift @ARGV;
die $usage unless defined $host and @ARGV;
my $ssh = Net::OpenSSH->new($host);
$ssh->error and die "Unable to connect to remote host: " . $ssh->error;
my @cmds;
for my $env (@envs) {
next unless defined $ENV{$env};
push @cmds, "export " . $ssh->shell_quote($env) .'='.$ssh->shell_quote($ENV{$env})
}
my $cmd = join('&&', @cmds, '('. join(' ', @ARGV) .')');
warn "remote command: $cmd\n";
$ssh->system($cmd);
如果您的环境变量包含引人注目的有趣内容,它就不会中断。
答案 5 :(得分:0)
此解决方案适合我。 假设您有两个参数或两个变量的脚本:
#!/bin/sh
echo "local"
echo "$1"
echo "$2"
/usr/bin/ssh root@192.168.1.2 "/path/test.sh \"$1\" \"$2\";"
在192.168.1.2上编写脚本test.sh:
#!/bin/bash
echo "remote"
echo "$1"
echo "$2"
输出将是:
local
This is first params
And this is second
remote
This is first params
And this is second