跳转至

脚本编写

概述

你可以创建一个脚本来自动执行一系列 iPXE 命令。任何可以在 iPXE 命令行上输入的命令也可以在脚本中使用。你可以在 iPXE 命令参考中找到完整的命令列表。

iPXE 脚本是一个以魔数行 #!ipxe 开头并包含一系列 iPXE 命令的纯文本文件。例如,这是一个通过 DHCP 获取 IP 地址然后启动 iPXE 演示镜像的简单脚本:

  #!ipxe

  dhcp
  chain http://boot.ipxe.org/demo/boot.php

这是另一个创建 VLAN 然后从中启动的简单脚本:

  #!ipxe

  vcreate --tag 24 net0
  autoboot net0-24

这是一个稍微复杂一些的脚本,它会持续重试 DHCP,直到成功获得启动文件名:

  #!ipxe

  :retry_dhcp
  dhcp && isset ${filename} || goto retry_dhcp
  echo Booting from ${filename}
  chain ${filename}

你可以使用任何文本编辑器创建 iPXE 脚本,例如 emacsvi,甚至 Windows 记事本。iPXE 脚本不需要任何特定的文件扩展名(例如 .txt.ipxe);只要它以魔数行 #!ipxe 开头,iPXE 就会把它识别为脚本。[^1]

流程控制

你可以使用 goto 命令跳转到预定义的脚本标签。你可以使用以下方式定义标签:

A flowchart

  :<label>

并使用以下方式跳转到此标签:

  goto label

例如:

  #!ipxe

  :loop
  echo Hello world
  goto loop

你可以使用 &&|| 运算符根据前面命令的状态有条件地执行命令。例如:

  dhcp && echo DHCP succeeded

  dhcp || echo DHCP failed

这些运算符可以与 goto 命令有效地结合,实现简单的条件流程控制。例如,持续重试 DHCP 直到成功:

  #!ipxe

  :retry_dhcp
  dhcp || goto retry_dhcp

你可以使用 ; 运算符来执行命令,无论前面命令的状态如何。例如:

  echo IP address: ${net0/ip} ; echo Subnet mask: ${net0/netmask}

你可以使用 exit 命令在任何时候终止脚本。

错误处理

Warning

如果脚本的任何一行失败,iPXE 将立即终止脚本。例如,如果你有脚本:

  #!ipxe

  dhcp
  route

那么如果 dhcp 命令失败,脚本将立即终止,不会继续执行下一行。你可以使用 || 运算符覆盖此行为:

  #!ipxe

  dhcp ||
  route

在此示例中,|| 运算符后的空命令被视为"什么都不做,且成功"(类似于类 Unix 操作系统上的 /bin/true)。因此,即使 dhcp 命令失败,这一行脚本的总体状态也将始终是"成功"。

注释

你可以使用 # 符号开始注释。例如:

  # Obtain an address using DHCP
  :retry
  dhcp || goto retry # Keep retrying indefinitely

行延续

为了提高可读性,可以使用反斜杠续行来拆分长脚本行。例如:

 choose --default linux --timeout 3000 os \
    && goto boot_${os} || goto cancelled

高级主题

An iPXE ROM

嵌入式脚本

你可以在 iPXE 中嵌入一个脚本来覆盖其默认行为。例如,你可能希望构建一个包含嵌入式脚本的 iPXE 版本,该脚本使用 DHCP 获取 IP 地址,但随后从预定义的 SAN 目标启动。

动态脚本

iPXE 脚本不必是静态文本文件。例如,你可以指示 iPXE 从以下 URL 启动:

  http://192.168.0.1/boot.php?mac=${net0/mac}&asset=${asset:uristring}

它将展开为类似这样的 URL:

  http://192.168.0.1/boot.php?mac=52:54:00:12:34:56&asset=BKQ42M1

运行在 Web 服务器上的 boot.php 程序可以根据 URL 中提供的信息动态生成脚本。例如,boot.php 可以在 MySQL 数据库中查找资产标签,以确定要从哪个正确的 iSCSI 目标启动,然后动态生成如下脚本:

  #!ipxe

  set initiator-iqn iqn.2010-04.org.ipxe:BKQ42M1
  sanboot iscsi:192.168.0.20::::iqn.2010-04.org.ipxe:winxp

[^1]: 为了向后兼容,iPXE 也会识别以魔数行 #!gpxe 开头的传统 gPXE 脚本。然而,gPXE 无法运行 iPXE 脚本,因为 iPXE 脚本语言比 gPXE 脚本语言先进得多。