上一主题: 使用 run-remote 命令下一主题: AutoShell 核心参考


使用 RemoteTarget 类

在以下方法中,将 run-remote 命令与 RemoteTarget 类结合使用:

run-remote 命令始终返回 RemoteTarget 对象的数组。 该数组的长度等于 on 子句中指定的远程目标的数目。 数组元素按位置直接对应于远程目标:

arrRT = run-remote -file hello.js on "ascl1", "ascl2"

run-remote 命令返回由两个 RemoteTarget 对象组成的数组。

RemoteTarget 对象提供脚本的状态信息,包括其执行过程、输出或结果。 以下 RemoteTarget 方法检索该状态信息:

hasCompleted()

指出命令处理是否已完成(true 或 false)。 如果不使用可选 -wait 开关调用 run-remote,命令执行会异步运行。 调用此方法以验证命令是否已完成及结果是否可用。 当命令成功完成时,方法 hasCompleted() 返回 true;当发生错误,阻止进一步处理时,返回 false。

返回值:true 或 false

errorOccurred()

指出是已成功完成命令且能够验证输出和结果 (false),还是发生错误 (true)。

返回值:true 或 false

output()

返回一个字符串,其中包含在相应远程系统上运行指定的脚本时生成的捕获输出。

返回值:string

result()

返回在相应的远程系统上执行的指定脚本的 XML 编码值。

返回值:XML

有关 RemoteTarget 类的其他方法,请参阅 AutoShell 类一节。

示例

假定先前介绍的 hello.js 脚本生成“Hello World!”问候语,则两个 RemoteTarget 对象的 output() 方法都返回该字符串。 以下脚本会将这种处理放入更大的上下文中:

var t;
var arrRT;
var i, l;

arrRT = run-remote -file hello.js on "ascl1", "ascl2"
l = arrRT.length;

// 等待完成,也可以使用上面的 -wait 子句
// 但通过这种方式,我们可以解决自己的超时
t = 0;

while(t<60)
{
    for(i=0; i<l; i++)
    {
        if(!arrRT[i].hasCompleted())
            break;    
    }
    // 如果所有调用都完成则中断
    if(i==l)
        break;
    sleep(500);
    t++;
}
for(i=0; i<l; i++)
{
    if(arrRT[i].hasCompleted())
    {
        if(arrRT[i].errorOccurred())
        {
            ? "Error occurred on ", arrRT[i].getHostName()
        }
        else
        {
            ? arrRT[i].getHostName(),"returned output:"
            ? arrRT[i].output()
        }
    }
    else
    {
        arrRT[i].abort();    
    }
}

通过将远程执行与 OS 命令调用相结合,可访问远程系统上的 OS 服务或数据。 例如,以下代码查询并返回在服务器 ascl1 上运行的操作系统的 OS 版本字符串。

arrRT = run-remote ! ver on "ascl1" -wait
? arrRT[0].output()

AutoShell 仅在上例中显示远程命令输出。 远程处理的表达式或脚本也能返回值:

arrRT = run-remote 2*21 on "ascl1" -wait

在这种情况下,将表达式“2*21”发送到服务器 ascl1 进行远程计算。 在命令完成时,通过相应 RemoteTarget 对象的 result() 方法可以获取结果。

result() 方法不是直接返回值,而是返回值的 XML 表示:

? arrRT[0].result()
<value type="number">42</value>

要将该 XML 字符串转换为常规 JavaScript 值,请使用 get-remoteResult():

v = get-remoteResult(arrRT[0])
? typeof v, v

AutoShell 序列化也适用于返回复杂类型(如数组或对象)的远程脚本。 序列化使大量结构化数据可在远程服务器之间传输,而不会丢失结构数据。 以下示例显示了返回包含三个元素的数组的远程执行:

arrRT = run-remote [1,"abc",new Date()] on "ascl1" -wait
v = get-remoteResult(arrRT[0])
? typeof v, v

处理 RemoteTarget 对象的另一种方法是在调用实际的远程命令之前创建 RemoteTarget 对象。 通过在对象创建中指定目标主机的名称,构造 RemoteTarget 对象:

var rt1 = new RemoteTarget("ascl1");
var rt2 = new RemoteTarget("ascl2");

为同一远程主机执行不止一个命令或脚本时,显式创建 RemoteTarget 对象很有用。 在这种情况下,每个 run-remote 命令可以重用同一 RemoteTarget 对象。 否则,run-remote 会为每个调用创建一个 RemoteTarget 对象。

要将 RemoteTarget 对象与 run-remote 结合使用,请指定它们,而不是主机名:

run-remote -file hello.js on rt1, rt2 -wait
? rt1.output()
? rt2.output()
run-remote Math.log(Math.E) on rt1, rt2
? get-remoteResult(rt1)
? get-remoteResult(rt2)

使用 RemoteTarget 对象时不需要存储 run-remote 返回的数组。 此数组仅包含对最初传递到命令的 RemoteTarget 对象的引用。 因此可以直接访问显式创建的 RemoteTarget 对象来查询执行的结果。

您可以在列表中指定远程目标,如在之前的示例中或作为数组。

arrRT = [new RemoteTarget("ascl1"), new RemoteTarget("ascl2")];
run-remote -file hello.js on arrRT

RemoteTarget 对象允许您在后续的 run-remote 命令调用中重用对象,还提供一种管理远程客户端会话创建的方法。

AutoShell 执行 run-remote 命令时,它会通过 SSH 连接到指定的远程系统。 默认情况下,远程系统上的 SSH 服务器会启动新的客户端 AutoShell 实例。 新创建的 AutoShell 进程评估所传递的脚本并在评估完成后被销毁。 对于随后的多个命令调用,将在远程系统上创建和销毁多个客户端 AutoShell 进程。 另外,在运行脚本时创建的任何上下文信息都将丢失,无法用于随后的远程脚本。

RemoteTarget 类实施一种易于使用的机制来控制远程主机上的客户端 AutoShell 会话创建。 在 RemoteTarget 对象上调用 createRemoteContext(),以在远程主机上为该 RemoteTarget 对象创建永久客户端 AutoShell 会话:

var rt = new RemoteTarget("ascl1");
rt.createRemoteContext()

随后的 run-remote 调用不会在远程主机上分配临时的客户端 AutoShell 会话,而是使用 createRemoteContext() 创建的永久会话。 另外,在运行脚本时创建的任何上下文信息可用于稍后执行的任何远程脚本。 在收集 RemoteTarget 对象时,将自动销毁远程主机上的永久客户端 AutoShell 会话。 也可通过在对应的对象上调用 destroyRemoteContext() 来显式销毁会话。

使用以下示例可轻松验证使用 createRemoteContext() 的效果:

var rt = new RemoteTarget("ascl1");
rt.createRemoteContext()
run-remote X=5 on rt -wait
run-remote X on rt -wait 
? get-remoteResult(rt)
rt.destroyRemoteContext()
run-remote X=5 on rt -wait
run-remote X on rt -wait
? get-remoteResult(rt)

第二个命令调用返回 5,因为在第一个调用中创建的变量 X 仍然存在于永久客户端 AutoShell 会话中。 销毁远程客户端会话后,剩下的两个调用将触发创建两个临时客户端 AutoShell 会话的操作。 第二个命令返回空结果,因为在其他会话中创建的变量 X 已被销毁。

详细信息

RemoteTarget 类