脚本¶
概述¶
你可以创建脚本来自动化执行一系列 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 脚本,比如 emacs、vi,甚至 Windows 记事本。iPXE 脚本不需要特定的文件扩展名(如 .txt 或 .ipxe);只要以魔数行 #!ipxe 开头,iPXE 就会把它识别为脚本。[^1]
流程控制¶

你可以使用 goto 命令跳转到预定义的脚本标签。定义标签的语法是:
:<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 命令终止脚本。
错误处理¶

如果脚本的任意一行执行失败,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
高级主题¶

嵌入式脚本¶
你可以在 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 脚本语言先进得多。