Linux 在远程 ssh 命令中传递变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3314660/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 20:17:00  来源:igfitidea点击:

Passing variables in remote ssh command

linuxbashshellssh

提问by Fergal

I want to be able to run a command from my machine using ssh and pass through the environment variable $BUILD_NUMBER

我希望能够使用 ssh 从我的机器运行命令并传递环境变量 $BUILD_NUMBER

Here's what I'm trying:

这是我正在尝试的:

ssh [email protected] '~/tools/myScript.pl $BUILD_NUMBER'

$BUILD_NUMBERis set on the machine making the ssh call and since the variable doesn't exist on the remote host, it doesn't get picked up.

$BUILD_NUMBER设置在进行 ssh 调用的机器上,并且由于远程主机上不存在该变量,因此不会被拾取。

How do I pass the value of $BUILD_NUMBER?

我如何传递 的值$BUILD_NUMBER

采纳答案by sarnold

If you use

如果你使用

ssh [email protected] "~/tools/run_pvt.pl $BUILD_NUMBER"

instead of

代替

ssh [email protected] '~/tools/run_pvt.pl $BUILD_NUMBER'

your shell will interpolate the $BUILD_NUMBERbefore sending the command string to the remote host.

您的 shell 将$BUILD_NUMBER在将命令字符串发送到远程主机之前插入。

回答by Stephen

Variables in single-quotes are not evaluated. Use double quotes:

不计算单引号中的变量。使用双引号:

ssh [email protected] "~/tools/run_pvt.pl $BUILD_NUMBER"

The shell will expand variables in double-quotes, but not in single-quotes. This will change into your desired string before being passed to the sshcommand.

shell 将用双引号而不是单引号来扩展变量。这将在传递给ssh命令之前更改为您想要的字符串。

回答by Sarah Gruneisen

Escape the variable in order to access variables outside of the ssh session: ssh [email protected] "~/tools/myScript.pl \$BUILD_NUMBER"

转义变量以访问 ssh 会话之外的变量:ssh [email protected] "~/tools/myScript.pl \$BUILD_NUMBER"

回答by Gilles Gouaillardet

As answered previously, you do not need to set the environment variable on the remote host. Instead, you can simply do the meta-expansion on the local host, and pass the value to the remote host.

如前所述,您不需要在远程主机上设置环境变量。相反,您可以简单地在本地主机上进行元扩展,并将值传递给远程主机。

ssh [email protected] '~/tools/run_pvt.pl $BUILD_NUMBER'

If you really want to set the environment variable on the remote host and use it, you can use the envprogram

如果你真的想在远程主机上设置环境变量并使用它,你可以使用env程序

ssh [email protected] "env BUILD_NUMBER=$BUILD_NUMBER ~/tools/run_pvt.pl $BUILD_NUMBER"

In this case this is a bit of an overkill, and note

在这种情况下,这有点矫枉过正,请注意

  • env BUILD_NUMBER=$BUILD_NUMBERdoes the meta expansion on the local host
  • the remote BUILD_NUMBERenvironment variable will be used by
    the remote shell
  • env BUILD_NUMBER=$BUILD_NUMBER在本地主机上进行元扩展
  • 远程BUILD_NUMBER环境变量将被
    远程 shell 使用

回答by Alice M.

(This answer might seem needlessly complicated, but it's easily extensible and robust regarding whitespace and special characters, as far as I know.)

(这个答案可能看起来不必要地复杂,但据我所知,它在空格和特殊字符方面很容易扩展和健壮。)

You can feed data right through the standard input of the sshcommand and readthat from the remote location.

您可以直接通过ssh命令的标准输入和read来自远程位置的输入来提供数据。

In the following example,

在下面的例子中,

  1. an indexed array is filled (for convenience) with the names of the variables whose values you want to retrieve on the remote side.
  2. For each of those variables, we give to ssha null-terminated line giving the name and value of the variable.
  3. In the shhcommand itself, we loop through these lines to initialise the required variables.
  1. 一个索引数组(为方便起见)填充有您想要在远程端检索其值的变量的名称。
  2. 对于这些变量中的每一个,我们给出ssh一个以空字符结尾的行,给出变量的名称和值。
  3. shh命令本身中,我们循环遍历这些行以初始化所需的变量。
# Initialize examples of variables.
# The first one even contains whitespace and a newline.
readonly FOO=$'apjlljs ailsi \n ajlls\t éjij'
readonly BAR=ygnàgyààynygbjrbjrb

# Make a list of what you want to pass through SSH.
# (The “unset” is just in case someone exported
# an associative array with this name.)
unset -v VAR_NAMES
readonly VAR_NAMES=(
    FOO
    BAR
)

for name in "${VAR_NAMES[@]}"
do
    printf '%s %s
FOO = [$'apjlljs ailsi \n ajlls\t éjij']; BAR = [ygnàgyààynygbjrbjrb]
' "$name" "${!name}" done | ssh [email protected] ' while read -rd '"''"' name value do export "$name"="$value" done # Check printf "FOO = [%q]; BAR = [%q]\n" "$FOO" "$BAR" '

Output:

输出:

$ ssh [email protected] 'read foo' <<< "$foo"

If you don't need to exportthose, you should be able to use declareinstead of export.

如果你不需要export这些,你应该可以使用declare代替export.

A really simplified version(if you don't need the extensibility, have a single variable to process, etc.) would look like:

一个真正简化的版本(如果您不需要可扩展性,需要处理单个变量等)将如下所示:

AcceptEnv BORG_*

回答by TvE

It is also possible to pass environment variables explicitly through ssh. It does require some server-side set-up through, so this this not a universal answer.

也可以通过 ssh 显式传递环境变量。它确实需要一些服务器端设置,所以这不是一个通用的答案。

In my case, I wanted to pass a backup repository encryption key to a command on the backup storage server without having that key stored there, but note that any environment variable is visible in ps! The solution of passing the key on stdin would work as well, but I found it too cumbersome. In any case, here's how to pass an environment variable through ssh:

就我而言,我想将备份存储库加密密钥传递给备份存储服务器上的命令,而不将该密钥存储在那里,但请注意,任何环境变量都在ps! 在 stdin 上传递密钥的解决方案也可以,但我发现它太麻烦了。无论如何,以下是通过 ssh 传递环境变量的方法:

On the server, edit the sshd_configfile, typically /etc/ssh/sshd_configand add an AcceptEnvdirective matching the variables you want to pass. See man sshd_config. In my case, I want to pass variables to borg backup so I chose:

在服务器上,sshd_config通常编辑文件/etc/ssh/sshd_config并添加AcceptEnv与您要传递的变量匹配的指令。见man sshd_config。就我而言,我想将变量传递给 borg 备份,所以我选择了:

$ BORG_SECRET=magic-happens ssh -o SendEnv=BORG_SECRET backup printenv | egrep BORG
BORG_SECRET=magic-happens

Now, on the client use the -o SendEnvoption to send environment variables. The following command line sets the environment variable BORG_SECRETand then flags it to be sent to the client machine (called backup). It then runs printenvthere and filters the output for BORG variables:

现在,在客户端使用-o SendEnv选项发送环境变量。以下命令行设置环境变量BORG_SECRET,然后将其标记为发送到客户端计算机(称为backup)。然后在printenv那里运行并过滤 BORG 变量的输出:

LC_MY_BUILDN="1.2.3" ssh -o "SendEnv LC_MY_BUILDN" ssh-host 'echo $LC_MY_BUILDN'
1.2.3

回答by Alex Stragies

The list of accepted environment variables on SSHD by default includes LC_*. Thus:

默认情况下,SSHD 上接受的环境变量列表包括LC_*. 因此:

##代码##