Shell脚本:通过ssh运行脚本中的函数

64

有没有巧妙的方法可以通过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

是的,我知道它不起作用,但有没有一种方法可以实现这个目标?

3个回答

132

您可以使用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执行前将函数的定义内联。


4
最好使用 typeset -f f 命令,只发送一个函数的定义即可。 - Henk Langeveld
10
这取决于f()是否需要调用其他必要的函数。在我看来,函数f()可能需要其他函数。否则,你的建议会是最好的。 - alvits
3
你可以像处理任何其他命令一样使用相同的方式传递参数。如果函数名为f(),那么你可以像这样传递参数:f param1 param2 ...。在f()函数内部,你可以通过$1, $2, ..., $n来引用这些参数。 - alvits
2
太好了!我在Bash中使用了declare -f而不是typeset -f。谢谢。 - Felipe Alvarez
2
当使用declare -ftypset -f时,我会收到syntax error near unexpected token ;的语法错误提示。 - guygrinberger
显示剩余5条评论

7

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

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

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

5
另一种方法:
#!/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 打印函数定义


声明未找到。 - Ashish Karpe
如何调用多个函数? - Varsh
@Varsh 可以像这样传输多个函数:$(declare -f bar foo); foo - Stefan Zhelyazkov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接