【问题标题】:Quoting with ssh command with a function call通过函数调用引用 ssh 命令
【发布时间】:2015-05-18 23:45:06
【问题描述】:

我需要执行shell命令如下:

ssh <device> "command"

命令被调用为:

$(typeset); <function_name> \"arguement_string\"; cd ...; ls ... 

这里具体怎么引用?这是正确的吗?

""$(typeset); <function_name> \"arguement_string\""; cd ...; ls ..."

我对 shell 脚本中的这种引用感到困惑。

【问题讨论】:

  • 不要双引号。只需转义内部字符串中的任何内容。
  • 请更准确地描述你想要做什么。以编程方式生成 ssh 命令(如果这是您正在尝试的)很棘手;如果我们要让它们正确,我们需要知道细节。 (如果您只是想传递一个常量脚本,那么@hek2mgl 的现有答案是正确的)。

标签: linux bash shell ssh


【解决方案1】:

不要尝试手动进行引用——让 shell 为你做!

command_array=( function_name "first argument" "second argument" )
printf -v command_str '%q ' "${command_array[@]}"
ssh_str="$(typeset); $command_str"
ssh machine "$ssh_str"

然后您可以根据需要构建command_array - 使用逻辑有条件地附加值,仅使用您通常引用的引用类型来引用这些值,并让printf %q 添加所有需要的额外引用使内容可以安全地通过 ssh。


如果您尝试逐步构建脚本,您可以这样做:

remote_script="$(typeset)"$'\n'
safe_append_command() {
  local command_str
  printf -v command_str '%q ' "$@"
  remote_script+="$command_str"$'\n'
}

safe_append_command cp "$file" "$destination"
safe_append_command tar -cf /tmp/foo.tar "${destination%/*}"
# ...etc...

ssh machine "$remote_script"

请注意,在这种情况下,所有扩展都发生在本地,在生成脚本时,并且不能使用诸如重定向运算符之类的 shell 构造(除非将它们嵌入到您随后传递的函数中到远程系统typeset)。这样做意味着传递给 safe_append_command 的任何数据都不能被视为代码 - 以牺牲灵活性为代价避免了大量潜在的安全漏洞。

【讨论】:

    【解决方案2】:

    我会使用here document:

    ssh machine <<'EOF'
    hello() {
        echo "hello $1!"
    }
    
    hello "world"
    EOF
    

    请注意,我将开头的 EOF 包裹在单引号中。这样做可以防止 bash 在本地 shell 中解释变量或命令替换。

    【讨论】:

    • 如果远程脚本要保持不变,这绝对是正确的。我不确定这个问题是否说明了这种情况。
    猜你喜欢
    • 1970-01-01
    • 2015-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-08
    • 2011-01-25
    • 1970-01-01
    • 2012-09-05
    相关资源
    最近更新 更多