文章目录

  • 在Shell脚本中通过ssh从脚本运行函数
  • declare -f 和typset -f,这两个命令有什么区别
  • declare -f 和typset -f,这两个命令可以通过ssh运行脚本中的函数吗
  • 如果我有main.sh和util.sh,并且在main.sh中引用了util.sh,该怎么办? 我应该如何通过ssh执行main.sh而不将utils.sh复制到远程计算机?


在Shell脚本中通过ssh从脚本运行函数

是否有任何聪明的方法可以通过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

以上操作时行不通的,我知道这行不通,但是有办法实现吗?


以下是相关解决方法:

可以使用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将成为远程shell中的已定义函数。最后,该功能可以执行。

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



相关讨论如下:

最好使用typeset -f f,并且只跨发送一个函数的定义
@HenkLangeveld-取决于是否有f()调用所需的函数。 在我的假设中,函数f()可能需要其他函数。 否则,您的建议将是最好的。
如何将一些参数传递给此函数?
使用任何命令的方式相同。 如果函数是f(),则可以传递f param1 param2 ...之类的参数。 在f()内部,您将把参数引用为$1, $2, ... $n
优秀的! 对于Bash,我使用declare -f而不是typeset -f。 谢谢。
当我使用它说" COMMAND NOT FOUND"(未找到命令)之类的函数时,是否定义了该函数?
@alvits很好。 但是,如果我有main.shutil.sh,并且在main.sh中引用了util.sh,该怎么办? 我应该如何通过ssh执行main.sh而不将utils.sh复制到远程计算机?
使用declare -ftypset -f时得到syntax error near unexpected token ;

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

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

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

这个方法就是相当于ssh登录远程主机后,向远程主机发送myFile脚本,然后执行脚本,执行脚本中的f函数,执行完毕后rm删除myFile脚本。

另一种方式:

#!/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"
ssh user@host"$(declare -f foo);foo"

这个命令是一个使用 SSH 远程调用函数的例子。下面是解释:

ssh 是远程登录协议,允许用户在不同计算机之间进行安全的远程登录和执行命令。
user@host 是你要连接的远程主机的用户名和 IP 地址或域名。
$(declare -f foo) 是将本地函数 foo 的定义转换为字符串并传递到远程主机上执行的命令。这样可以确保在远程主机上也有 foo 函数的定义。
; foo 在声明完函数后立即调用了函数 foo。

以下是示例代码:
假设你在本地机器上定义了一个名为 hello_world 的函数,并且你希望在远程主机 example.com 上执行该函数。你可以使用以下命令:

ssh user@example.com "$(declare -f hello_world); hello_world"

当你执行这个命令时,它会将本地的 hello_world 函数定义作为字符串传输到远程主机,并在远程主机上执行该函数。如果一切正常,你应该看到输出结果 Hello, World!

declare -f 和typset -f,这两个命令有什么区别

declare -f 和 type -f 都是用来查看函数定义的命令,
但是它们具有不同的作用和输出形式:

  1. declare -f function_name

declare -f 命令用于显示指定函数的定义(包括函数名、参数和函数体)。如果没有指定函数名称,则显示所有已定义的函数。

示例代码:

# 定义函数
function hello() {
    echo "Hello, world!"
}

# 使用 declare -f 输出函数定义
declare -f hello

# 输出结果为:
# hello () 
# { 
#     echo "Hello, world!"
# }

# 不传递函数名称,显示所有已定义的函数
declare -f
  1. type -f function_name

type -f 命令用于显示指定函数的位置(即函数所在文件的路径)。

示例代码:

# 定义函数
function hello() {
    echo "Hello, world!"
}

# 使用 type -f 输出函数位置
type -f hello

# 输出结果为:hello is a function
# hello () 
# { 
#     echo "Hello, world!"
# }

# 如果该函数在 bash 脚本中,也可以使用 type 来查看文件位置
type -f my_script.sh

因此,declare -ftype -f 的区别在于前者用于显示函数定义,后者用于显示函数位置。


declare -f 和typset -f,这两个命令可以通过ssh运行脚本中的函数吗

在Shell脚本中,可以使用ssh命令从本地机器远程登录到另一台远程机器,并在远程机器上执行命令或运行脚本。如果想要在远程机器上运行脚本中的函数,可以通过ssh命令来实现。

在使用ssh命令远程执行命令或脚本时,默认情况下不会传输环境变量或函数定义等内容。因此,为了能够在远程机器上运行脚本中的函数,需要将函数定义先传输到远程机器上,然后再调用这些函数。declare -f和typset -f命令可以分别用于显示和导出当前Shell环境中的函数定义。

例如,假设在本地机器上有一个脚本test.sh,其中包含一个名为my_function的函数。现在我们想要在远程机器上运行这个函数。我们可以使用以下命令:

$ ssh remote_host "$(declare -f my_function); my_function"

该命令将首先使用declare -f my_function显示my_function函数的定义,然后将其作为参数传递给ssh命令。在远程主机上,该命令将首先定义my_function函数,然后调用它以执行相应的操作。

类似地,也可以使用typset -f命令来显示并导出当前Shell环境中的函数定义。例如:

$ ssh remote_host "$(typset -f my_function); my_function"

需要注意的是,如果函数依赖于某些环境变量或命令,则需要在远程机器上设置这些环境变量或安装相应的命令才能正常运行。


如果我有main.sh和util.sh,并且在main.sh中引用了util.sh,该怎么办? 我应该如何通过ssh执行main.sh而不将utils.sh复制到远程计算机?

要在远程计算机上执行main.sh并引用本地计算机上的util.sh,您可以使用SSH远程执行命令来完成此操作。具体步骤如下:

  1. 在本地计算机上,将util.sh压缩为tar.gz文件,例如:
tar -czf util.tar.gz util.sh
  1. 使用scp命令将util.tar.gz文件复制到远程计算机上,例如:
scp util.tar.gz remoteuser@remotehost:/tmp/

其中remoteuser是远程计算机上的用户名,remotehost是远程计算机的地址,/tmp/是目标文件夹。

  1. 在远程计算机上,通过ssh连接到该计算机,并切换到main.sh所在的目录。
  2. 解压缩util.tar.gz文件,并在main.sh中引用util.sh文件。例如:
tar -xzf /tmp/util.tar.gz -C /tmp/
source /tmp/util.sh

# 继续main.sh中的其他命令
  1. 执行main.sh脚本。
./main.sh
  1. 执行完main.sh后,可以删除已解压的util.sh文件和tar.gz文件。
rm /tmp/util.sh /tmp/util.tar.gz

这样就可以在不将util.sh复制到远程计算机的情况下,成功运行main.sh并引用util.sh文件了。