【问题标题】:Invoke function from bash heredoc从 bash heredoc 调用函数
【发布时间】:2021-07-21 08:46:13
【问题描述】:

我正在从一个克隆存储库的 heredoc 中调用一个函数。但是存储库是在本地机器上克隆的,而不是在我想要的远程机器上。该脚本在本地机器上执行。

_git_clone() {
    git clone myrepo
    git fetch --all --tags
}

ssh myserver <<EOF
    echo $(_git_clone)
EOF

问题 2) git fetch 仅将“Fetching origin”打印到控制台而不是整个获取日志。我们如何使该命令将完整日志打印到控制台。

【问题讨论】:

    标签: linux bash unix heredoc


    【解决方案1】:

    确切地说,这是使用 i0b0 的回答中的想法解决了我的问题:

    _git_clone() {
        git clone myrepo
        git fetch --all --tags
    }
    
    ssh myserver <<EOF
        $(declare -f _git_clone)
        _git_clone
    EOF
    
    

    所以解决方法是在 heredoc 中声明函数,然后将调用移出命令替换。

    【讨论】:

      【解决方案2】:

      here 文档的内容在本地求值,就像用双引号括起来的字符串一样。为避免这种行为,您需要“引用”here 文档,如下所示:

      ssh myserver <<'EOF'
        echo $(_git_clone)
      EOF
      

      当然,这仍然行不通,因为您已经在本地定义了_git_clone 函数,所以在远程系统上您只会看到bash: _git_clone: command not found...。如果您希望该功能远程可见,则需要进入您的 here 文档:

      ssh myserver <<'EOF'
          _git_clone() {
              git clone myrepo
              git fetch --all --tags
          }
      
          echo $(_git_clone)
      EOF
      

      但这似乎不必要地复杂;你不妨这样做:

      ssh myserver <<EOF
          git clone myrepo
          git fetch --all --tags
      EOF
      

      here 文档语法的 bash 手册页的相关部分位于“Here Documents”部分,内容如下:

      here-documents格式如下:

      <<[-]word
              here-document
      delimiter
      

      无参数扩展、命令替换、路径名扩展,或 对 word 进行算术扩展。 如果单词中有任何字符 被引用,分隔符是单词上引号删除的结果, 并且 here-document 中的行没有展开。

      我已经强调了关键信息。

      【讨论】:

        【解决方案3】:

        您需要将代码逐字传输到另一台服务器以在那里运行它。带有不带引号的起始分隔符的heredoc 的工作方式类似于双引号字符串,这意味着任何命令替换,如您在之前 运行的命令替换,结果字符串被传递到远程服务器。您可以通过将函数定义放在 heredoc 中并单引号括起起始分隔符来解决此问题:

        ssh myserver <<'EOF'
        _git_clone() {
            git clone myrepo
            git fetch --all --tags
        }
        echo $(_git_clone)
        EOF
        

        或者,您可以在本地定义函数,然后在 heredoc 中替换它的定义:

        _git_clone() {
            git clone myrepo
            git fetch --all --tags
        }
        
        ssh myserver <<EOF
        $(declare -f _git_clone)
        EOF
        

        【讨论】:

        • 我刚刚尝试了选项 2,我得到了这个:-bash: line 2: _git_clone: command not found
        • 您需要不加引号的分隔符才能使用第二个选项。否则,它会尝试在尚未定义的其他主机上运行该函数。
        • 好的,是的,我打算在其他主机上运行它,这就是我添加引号的原因。如果我删除它们,它可以工作,但随后将其克隆到本地机器。
        猜你喜欢
        • 2012-02-07
        • 2019-04-07
        • 1970-01-01
        • 2016-02-01
        • 2011-03-25
        • 1970-01-01
        • 1970-01-01
        • 2015-01-21
        相关资源
        最近更新 更多