【问题标题】:Passing methods to heredocs将方法传递给 heredocs
【发布时间】:2015-11-04 22:53:15
【问题描述】:

我需要通过ssh在大量主机上调用一些代码。

我尝试使用所谓的heredocs

function verifyFiles {
    ...
}

...

ssh user@$server <<-SSH
    cd $DIRECTORY
    verifyFiles
    createSum
    copyFiles
SSH

ssh user@server2 <<-SSH
    cd $DIRECTORY
    verifyFiles
    verifySums
SSH
...

不幸的是,以这种方式使用的函数在服务器端是未知的。

有没有一种优雅的方式来使用这些函数而不将它们粘贴到每个heredoc 中?

附言。每个主机上的代码调用略有不同,但使用相同的函数集。我真的很想在代码中拥有每个方法定义的 1 个副本。

PS2。当然,如果有更好的方法来调用此代码,我不必使用heredocs

【问题讨论】:

  • 请花一点时间考虑一下这应该如何工作。您已在本地计算机上定义了该函数,但即将远程执行它。
  • 当然,我做到了。我明白为什么它不能以这种方式工作。我只是不知道如何在不重复代码的情况下以一种优雅而简短的方式实现我的目标。
  • 好像我看错了,你需要一种模板代码而不是文本的方法,所以我之前的评论不合适
  • 另一个建议只是传递(通过 ssh)bash 脚本,然后通过 ssh 远程调用调用它们(因此它们将在远程机器上)。虽然不建议这样做,除非你对这些远程机器有绝对的访问权(并且可以容忍某事出错)
  • 我必须制作大量不同的文件并将正确的文件复制到正确的远程主机。我真的很想把它放在一个简单的脚本中,你知道,只需运行它。 :)

标签: bash shell ssh heredoc


【解决方案1】:

如果您有一个本地函数fooX 可以在每个hostX 上远程执行,您可以通过ssh 在各自的主机上定义并执行它,如下所示:

#!/bin/bash

function foo1() {
    echo foo
}

function foo2() {
    echo f0o
}

function remotefn() {
    # echo the function definition:
    type "$1" | tail -n +2
    # echo the function call:
    echo "$1"
}

while read user host fn
do
    # remotely execute function definition and the function itself:
    remotefn "$fn" | ssh "$user"@"$host"
done <<END
user1 host1 foo1
user2 host2 foo2
END

注意循环后的heredoc如何灵活地将函数映射到用户和主机。 ssh 将在各自的主机上读取并执行remotefn 提供的每个函数定义和函数调用。

【讨论】:

    【解决方案2】:

    这个怎么样?

    funs='
      foo() { echo "foo"; }
      bar() { local a; for a in "$@"; do echo "$a"; done; }
    '
    # eval "$funs"  # if you want the functions locally as well
    ssh user@$server1 <<-____HERE
        cd $DIRECTORY
        $funs
        foo && bar some args
    ____HERE
    

    不是一个特别令人满意的解决方案,但我相信它满足您的要求。

    【讨论】:

    • 不是一个非常优雅的解决方案,因为函数以字符串的形式保存。但是,嗯……一切都只写一次就可以了。
    • 在认为我“不接受”原因之后,也许有更好的方法可以在许多主机上远程使用预定义的功能。
    • 你可以有一个你 scp 的文件然后来源,但它并没有真正为你买任何东西,除非你需要在函数中更复杂的引用(在这种情况下使用它们因为字符串会变得笨拙和/或不安全)。
    • @aerion:到目前为止已经有 3 个不同的答案。您能否提供一些细节说明您希望您的解决方案以何种方式“更好”?例如。功能缺失、可读性等。
    • 我想这个问题没有客观的最佳解决方案。所有答案都有优点和缺点。因此很难选择一个“正确”。
    【解决方案3】:

    由于 here-documents 经历了各种扩展,您可以通过参数替换而不是函数调用来实现您的目标:

    VERIFYFILES='ls; df'
    
    ssh user@$server <<-SSH
        cd $DIRECTORY
        $VERIFYFILES
    SSH
    

    【讨论】:

    • 但是,当函数需要访问变量或参数时,这会发生故障,因此不幸的是,它的用途相当有限。
    • 很公平。但是 OP 的代码没有,如果有的话,我总是会寻求一种低技术、非火箭科学的解决方案。 :-)
    猜你喜欢
    • 2011-01-01
    • 2021-04-25
    • 2014-06-03
    • 2011-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-05
    相关资源
    最近更新 更多