【问题标题】:How do I pass arbitrary arguments to a command executed over SSH? [duplicate]如何将任意参数传递给通过 SSH 执行的命令? [复制]
【发布时间】:2018-07-26 21:28:16
【问题描述】:

假设我在远程服务器example.com 上的~/echo.sh 有一个包含以下内容的脚本:

#!/usr/bin/env bash
echo "Arg 1: $1"
echo "Arg 2: $2"
echo "Arg 3: $3"
echo "Arg 4: $4"

现在,在我的本地机器上,我有另一个脚本,remote-echo.sh,其内容如下:

#!/usr/bin/env bash
ssh example.com "~/echo.sh $*"

这个想法是用户应该能够使用任何参数运行remote-echo.sh,并将这些参数转发到远程服务器上的~/echo.sh。

很遗憾,这不起作用:

$ ./remote-echo.sh "arg with space" "argwith\"quote" "arg3"
bash: -c: line 0: unexpected EOF while looking for matching `"'
bash: -c: line 1: syntax error: unexpected end of file

我该如何解决这个问题?我已经尝试使用$@ 而不是$*,但这对结果根本没有任何影响。

【问题讨论】:

  • 我相信这个问题已经在知识库中,顺便说一句,具有相同的 (printf '%q ') 答案......以及其他一些更便携的答案(因为 bash 的 printf %q 不能保证生成对/bin/sh 有效的输出)。
  • ...出于这个原因,我有时会使用 Python 的 pipes.quote() 函数(在 Python 2 中,shlex.quote() 在 Python 3 中)代替,当不确定哪个 shell 将被使用时在远端。
  • ...链接的重复项,stackoverflow.com/questions/45308395/… 特别涵盖了这种情况。

标签: bash shell ssh


【解决方案1】:

您需要确保传递给 SSH 的字符串中嵌入的所有参数都被正确转义,因此它们不会被远程服务器上的 shell 解释。最简单的方法是在 Bash 中为printf 使用%q 格式字符:

#!/usr/bin/env bash
ssh example.com "~/echo.sh $(printf "%q " "$@")"

根据help Bash 中 printf 的信息:

除了 printf(1) 中描述的标准格式规范,printf 还解释:

[...]

%q 引用参数的方式可以作为 shell 输入重复使用

这应该可以解决您在此处看到的问题,并确保每个参数都正确传递给echo.sh。

【讨论】:

  • 请注意,您使用的 printf 可能是内置的 shell,即手册页不相关 - help printf 将是要查看的文档。如果我没记错的话,内置的printf 在Coreutils 中引入了%q。
  • 那里的“提议”一词也相当关键。 $'' 目前不是 POSIX sh 标准的一部分,/bin/sh 的常见版本(包括破折号)目前不支持它。
猜你喜欢
  • 2017-05-18
  • 1970-01-01
  • 1970-01-01
  • 2021-11-29
  • 2020-07-02
  • 1970-01-01
  • 1970-01-01
  • 2021-04-21
  • 1970-01-01
相关资源
最近更新 更多