【问题标题】:Shell script: Run function from script over sshShell 脚本:通过 ssh 从脚本运行函数
【发布时间】:2014-04-02 04:33:39
【问题描述】:

有什么聪明的方法可以通过 ssh 在远程主机上运行本地 Bash 函数吗?

例如:

#!/bin/bash
#Definition of the function
f () {  ls -l; }

#I want to use the function locally
f

#Execution of the function on the remote machine.
ssh user@host f

#Reuse of the same function on another machine.
ssh user@host2 f

是的,我知道这行不通,但是有没有办法做到这一点?

【问题讨论】:

    标签: linux bash shell sh


    【解决方案1】:

    您可以使用typeset 命令通过ssh 使您的功能在远程计算机上可用。有几个选项取决于您希望如何运行远程脚本。

    #!/bin/bash
    # Define your function
    myfn () {  ls -l; }
    

    在远程主机上使用该功能:

    typeset -f myfn | ssh user@host "$(cat); myfn"
    typeset -f myfn | ssh user@host2 "$(cat); myfn"
    

    更好的是,为什么还要管管道:

    ssh user@host "$(typeset -f myfn); myfn"
    

    或者您可以使用 HEREDOC:

    ssh user@host << EOF
        $(typeset -f myfn)
        myfn
    EOF
    

    如果您想发送脚本中定义的所有函数,而不仅仅是myfn,只需像这样使用typeset -f

    ssh user@host "$(typeset -f); myfn"
    

    说明

    typeset -f myfn 将显示myfn 的定义。

    cat 将接收函数的定义作为文本,$() 将在当前 shell 中执行它,这将成为远程 shell 中的定义函数。终于可以执行函数了。

    最后的代码会在 ssh 执行之前将函数的定义内联。

    【讨论】:

    • 最好使用typeset -f f,并且只发送一个函数的定义
    • @HenkLangeveld - 这取决于是否有 f() 调用的必需函数。在我的假设中,函数 f() 可能需要其他函数。否则你的建议是最好的。
    • 与任何命令一样。如果函数是f(),那么您可以传递f param1 param2 ... 之类的参数。在f() 中,您将引用参数为$1, $2, ... $n
    • 太棒了!我在 Bash 中使用了 declare -f 而不是 typeset -f。谢谢。
    • 我在使用declare -ftypset -f 时得到syntax error near unexpected token ;
    【解决方案2】:

    我个人不知道你的问题的正确答案,但我有很多安装脚本只是使用 ssh 复制自己。

    让命令复制文件,加载文件函数,运行文件函数,然后删除文件。

    ssh user@host "scp user@otherhost:/myFile ; . myFile ; f ; rm Myfile"
    

    【讨论】:

      【解决方案3】:

      另一种方式:

      #!/bin/bash
      # Definition of the function
      foo () {  ls -l; }
      
      # Use the function locally
      foo
      
      # Execution of the function on the remote machine.
      ssh user@host "$(declare -f foo);foo"
      

      declare -f foo打印函数定义

      【讨论】:

      • 声明:未找到,
      • 如何调用多个函数?