命令执行(集群中)

命令执行提供了在集群执行相关命令的功能(如需在当前执行命令请参考 命令执行,或命令中的 on 参数传递 self

函数原型

和集群命令执行相关的两个函数为 runexec,二者所接收的参数和返回值都是一样的,仅在行为有所不同。

可以发现,这个名称和非集群中的 命令执行 是一致的,事实上,二者的区别主要在于是否传递了 on 参数

  • exec 会将命令的执行结果输出到终端,并在出现异常(例如退出码非 0)时中断脚本执行
  • run 不会将命令的执行结果输出到终端,同时在出现异常时也不会中断脚本执行(可利用返回的 result.error 和 result.code 查看)

参数 on:要执行的目标机器(必填)

on 参数可以传递一个 str 或 List[str] 类型的参数,用于指定在若干个机器上同时执行。指定列表时将合并列表中的机器列表并去重后执行。

on 指定的机器列表请参考 core.resolve,这里使用的模式是标准模式(standard)

第一个参数:要执行的命令

run 接收的第一个参数为要执行的命令,这一命令支持传递一个 str list 或是一个字符串。如果传递的是 str list 的话会进行参数 join

命令的行为根据 参数 bash 的行为而有所不同,具体请参考 要执行的命令

参数 bash(默认为 True)

是否使用 bash (login shell),默认是打开的,在某些异常情况下可以关闭

具体效果请参考 将执行的命令

参数 env(默认为空)

设定额外使用的环境变量,支持传递 List[str] 或 Dict[str, str] 类型

参数 realtime(默认为 False)

该参数仅在 exec 中有效

因 ambot-run 的 -o 参数为 beta 版本,因此本参数也可能在未来被取消,请尽可能避免依赖该参数的逻辑

是否开启运行结果的实时输出,等价于执行 ambot-run 时传递了 -o / --output 参数

返回结果相关的数据类型

exec 的返回值仅在 ambot-script engine v1.3 系中 v1.3.8 或更高版本、v1.4 系中 v1.4.0-rc.16 或更高版本才会返回

rexec.Results

Results 是一个 rexec.Serverrexec.Result 的 dict

迭代 iterate

可以对 Results 进行 for 循环,循环时取到的是 server 列表(该循环无序,且不保证稳定)

.items() →[(Server, Result)]

返回一个 (Server, Result) 的二元组,用于在 for 循环中同时得到 server 和 result 使用

下标取值 [<str/Server>] → <Result/None>

利用下标取值时可以利用 Server 对象(通常在 for 循环中使用)也可以利用 hostname / ip 字符串取值。

如果存在返回 Result 对象,如果不存在返回 None

assert

等同于对所有的 Result 进行 assert

服务器信息 rexec.Server

命令执行时所在的目标机器

属性数据类型说明
hoststr执行目标的 hostname
ipstr执行目标的 ip 地址
isLocalbool执行目标是否为本机

.one(*, allow_no=False, allow_multiple=False) -> Option[Result]

**如果 allow_no 和 allow_multiple 均为 False ** (默认)

如果这次 run/exec 调用只在一台机器上执行了,返回这个执行结果 如果不在任何一台机器上执行或是在多于一台的机器上执行了,报错退出

如果 allow_no=True

如果不在任何一台机器上执行,返回 None

如果 allow_multiple=True

如果在多于一台的机器上执行了,随机返回一个执行结果

返回结果 rexec.Result

属性数据类型说明
codeint退出码
outputbytes输出内容(包括 stdout 和 stderr,目前只支持合并输出)
error<str/None>错误信息(非 0 退出不认为是错误,通常的错误可能为命令不存在或超时等)

assert

当无错误且返回值为 0 时成功

等同于 assert(result.error == None, result.code == 0)

.server -> rexec.Server

返回产生这一结果的 Server

.outputString -> str

等同于 .output,但返回的数据类型是 str

示例

results = run("echo 123; echo 123", on=['prs-master', 'prs-sensor'])

for i, x in enumerate(results, 1):
    print("[Server {}] host={}, ip={}, isLocal={}".format(i, x.host, x.ip, x.isLocal))
    # print("    -> Exit with", results[x].code)

for server, result in results.items():
    print("[{}] (Exit with {})\n{}".format(server.host, result.code, string(result.output)))

assert(results)

高级功能

将执行的命令

要执行的命令会受到 bash 参数的影响

  • 对于 bash=False 时
    • 传递的字符串会被 shlex.split 后执行
    • 传递的列表会被直接执行,列表的第一个参数为要执行的程序(如果不为路径则从 PATH 环境变量中搜索执行)
  • 对于 bash=True (默认)时
    • 传递的字符串会作为 ["bash", "-c", "<something>" ] 中的第三个参数
    • 传递的列表会被 shlex.join 后作为上述的第三个参数执行