ssh进入服务器时,如何将环境变量从客户端传递到服务器?此环境变量在ssh的不同调用之间变化,因此我不想每次执行ssh调用时都覆盖$HOME/.ssh2/environment。我该怎么办?

评论

您的问题需要更具体一些。

这个问题对我来说很清楚。但是,在ssh手册页上,除了登录〜/ .ssh2 / environment之外,我看不到有任何其他方法,只能在登录服务器后手动设置变量,除非您修改〜/ .ssh2 / environment。

每次都是不同的变量吗?还是其他值?

如何通过ssh命令传递环境变量的可能重复项?

反之,因为它已经越来越流行了。年龄不重要。

#1 楼

当然,您可以在命令中设置环境变量,但是在引用时要格外小心:请记住,您的外壳程序将解析本地命令行,然后远程外壳程序将在其上使用字符串

如果希望变量在服务器上获得与客户端上相同的值,请尝试使用SendEnv选项: />但这需要服务器的支持。使用OpenSSH,必须在/etc/sshd_config中授权变量名。

如果服务器仅允许某些特定的变量名,则可以解决此问题;例如,一个常见的设置允许LC_*通过,您可以执行以下操作:

ssh -o SendEnv=MYVAR server.example.com mycommand


如果甚至没有LC_*,也可以在TERM环境变量中传递信息,它总是被复制(但是可能有一个长度限制)。您仍然必须确保远程外壳程序不会限制TERM变量来指定已知的终端类型。如果您不启动远程交互式shell,请将-t选项传递给ssh。

ssh -o SendEnv=LC_MYVAR server.example.com 'MYVAR=$LC_MYVAR; unset LC_MYVAR; export MYVAR; mycommand'


另一种可能性是直接在命令中定义变量:

env TERM="extra information:$TERM" ssh -t server.example.com 'MYVAR=${TERM%:*}; TERM=${TERM##*:}; export MYVAR; mycommand'


因此,如果传递局部变量:

ssh -t server.example.com 'export MYVAR="extra information"; mycommand'


但是,请注意引号问题:变量的值将直接插值到在远程执行的shell代码段中。上面的最后一个示例假定$LOCALVAR不包含任何单引号(')。

评论


非常感谢,我很生气,愚蠢的LC_ *变量是在ssh上导出的,您的回答将我指引到了哪里。我只需要在〜/ .ssh / config中禁用它

–akostadinov
2012年10月9日在16:37

我处于原始海报的状态,但是我要转发的变量是TERM,所以您的回答让我有些困惑。最近的OpenSSH版本是否已禁用此TERM自动转发功能?

–杜布
2012年11月20日18:15

@Doub默认是拒绝服务器端的所有环境变量,并根据管理员的需要在sshd_config中使用AcceptEnv指令。但是据我所知,TERM是经过特殊处理的,据我所知,无法在服务器端对其进行过滤(无论在任何配置设置下,它都在Shell的环境中设置)。您确定没有配置文件脚本覆盖它(例如/ etc / profile或〜/ .profile或〜/ .bashrc)吗?

–吉尔斯'所以-不再是邪恶的'
2012年11月20日18:24



@Gilles:我再次对其进行了测试,除非我将TERM明确添加到我的AcceptEnv指令中,否则不会传递TERM。我没有打开外壳程序,而是直接运行命令,例如:“ ssh -o SendEnv = TERM shell.example.com env”。这将打印所有环境变量,并且TERM仅在客户端的SendEnv和服务器的AcceptEnv中显示。如果我在AcceptEnv或SendEnv中运行“ ssh -o SendEnv = TERM shell.example.com echo \ $ {TERM}”,它会显示“哑巴”,我不确定它来自哪里(env甚至不在这种情况下列出TERM)。

–杜布
2012年11月27日14:37

@Doub哦,我明白了。仅当客户端请求服务器分配tty时,才传输TERM。如果远程没有终端,则传输TERM将毫无用处。指定命令时,如果要在远程端建立终端,则需要-t命令行选项(或〜/ .ssh / config中的RequestTTY)。

–吉尔斯'所以-不再是邪恶的'
2012年11月27日15:28

#2 楼

如果可以管理目标主机,则可以配置sshd以允许将本地环境变量传递到目标主机。

从sshd_config手册页:

 PermitUserEnvironment
     Specifies whether ~/.ssh/environment and environment= options in
     ~/.ssh/authorized_keys are processed by sshd.  The default is
     "no".  Enabling environment processing may enable users to bypass
     access restrictions in some configurations using mechanisms such
     as LD_PRELOAD.


sshd配置通常位于/etc/ssh/sshd_config

评论


知道默认情况下将其设置为“ no”非常有用!

–弥撒教
13-10-4在22:59

#3 楼

因此,在您的客户端上,您有一些环境变量,并且您希望该变量可用于远程命令吗?我认为没有办法让ssh神奇地传递它,但是您可能可以做这样的事情。不用使用,而是说:

ssh remote.host my_command


您可以这样做:

ssh remote.host env ENV_VAR=$ENV_VAR my_command


评论


“大概”?我希望在实际尝试此答案之前先阅读一下。没为我工作。

– tishma
17年1月4日在23:54

想详细说明收到的任何错误等吗?

– Pioto
17年1月30日,下午2:30

@pioto可能会引用,例如如果ENV_VAR中有空格

–马丁C.马丁
17年4月11日在13:32

在Mac上,您必须具有-t选项才能使用交互式版本,否则它会卡住。因此这可能起作用:$ ssh -t remote.host env ENV_VAR = $ ENV_VAR my_command

– muenalan
18年1月11日在9:53



#4 楼

在本地客户端上,可以在~/.ssh/config中添加SetEnv,例如

Host myhost
  SetEnv FOO=bar


注:检查man ssh_config

然后在服务器上,确保允许客户端在您的/etc/ssh/sshd_config配置文件中传递某些环境变量:

AcceptEnv LANG LC_* FOO BAR*


注意:检查man sshd_config

#5 楼

@emptyset的响应(对我不起作用)使我得到以下答案:

您可以将此命令添加到您的~/.ssh/authorized_keys文件中:

command="/usr/bin/env VARIABLE=<something> $SHELL" ssh-rsa <key>


export VARIABLE=<something>立即退出,并且SSH连接已关闭(将我锁定在服务器之外),而/usr/bin/env ... $SHELL将在修改后的环境下运行您的默认Shell。

评论


为我登录时,这只是挂起。当我删除它时,SSH恢复正常,并且得到了我通常的登录外壳。

–尼克·斯威汀(Nick Sweeting)
18年5月15日在3:16

@NickSweeting您是否尝试过用实际的shell替换$ SHELL?还要检查服务器上是否存在/ usr / bin / env。但是解决方案并不完美:我注意到当我想使用scp或内联命令时,它挂起了。

– Madprog
18年5月15日在15:50

是的,那是我尝试的第一件事。不幸的是,从来没有使它起作用,最终启用了PermitUserEnvironment yes并使用environment =“ ...”而不是command =“ ...”。

–尼克·斯威汀(Nick Sweeting)
18年5月16日在17:59



这对我来说很好。

–陶先生
19年4月16日在11:40

#6 楼

只需一个简单的命令:

ssh -t your_host_or_ip 'export some_var_name=whatever_you_want; bash'


#7 楼

您可以尝试调用自定义命令,前提是您具有无密码的ssh登录设置。在服务器上,编辑与客户端密钥相对应的〜/ .ssh / authorized_keys条目:

command="export VARIABLE=<something>" ssh-rsa <key>


在“强制命令”部分中的此链接处查找更多细节。

评论


我试过了,但是没有用。它运行命令并退出,因此没有交互会话。这是正常现象吗?如果是这样,那么如果您只想允许特定键触发特定命令,这可能会很有用,但是如果您要传递会话中使用的信息(如问题所述),那么该信息就没有用了。没有会议。

–iconoclast
11年7月7日在22:17

#8 楼

我正在为在主目录和/ etc中带有cramfs的设备进行OpenSSH的自定义构建,因此,如果不重建整个FS,〜/ .ssh / environment将无法正常工作,并且这些文件已在现场部署设备(嵌入式系统,因此使用CRAMFS)。您可以在sshd_config中指定authroized_keys文件的位置,但是由于某些原因,environment =仅适用于〜/ .ssh / authroized_keys中的环境变量。编辑/ etc / profile不是一个选择,我不得不将ssh加载到非标准目录中。在child_set_env(...“ MAIL” ...)之后的session.c中,只需添加您需要的环境变量(这是我所知道的一种技巧...),但是如果有人在会话中需要一些硬编码的env,从源代码编译,您可以执行此操作。 TGI-牙线