脚本编写¶
概述¶
你可以创建一个脚本来自动执行一系列 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 脚本语言先进得多。