如何在Bash中向QEMU传入完整的命令行参数?
问题描述
我的QEMU启动脚本如下:
KERNEL_CFG="-kernel Image -append \"root=/dev/vda1 nokaslr console=ttyAMA0 earlycon=pl011,mmio,0x09000000\"" DISK_CFG="-drive if=none,file=$DISKFILE,format=qcow2,id=hd1 -device virtio-blk-pci,drive=hd1,bootindex=0" sudo ./qemu-system-aarch64 \ -machine virt -cpu host -accel kvm \ -bios QEMU_EFI.fd \ -nographic \ -net user,hostfwd=tcp::2222-:22 -net nic \ -smp cpus=8 \ -m 4G \ $KERNEL_CFG \ $DISK_CFG
执行后返回错误:
sudo ./qemu-system-aarch64 -machine virt -cpu host -accel kvm -bios QEMU_EFI.fd -nographic -net user,hostfwd=tcp::2222-:22 -net nic -smp cpus=8 -m 4G -kernel Image -append '"root=/dev/vda1' nokaslr console=ttyAMA0 'earlycon=pl011,mmio,0x09000000"' -drive if=none,file=debian-10-nocloud-arm64-20230601-1398.qcow2,format=qcow2,id=hd0 -device virtio-blk-pci,drive=hd0,bootindex=1 qemu-system-aarch64: nokaslr: Could not open 'nokaslr': No such file or directory
请问如何正确向QEMU传入完整的命令行参数?
解决方法
问题出在shell对字符串变量的空格拆分机制:用普通字符串保存带空格的参数时,shell展开变量会把所有空格(包括-append引号内的空格)当成参数分隔符,导致nokaslr、console=ttyAMA0这些本该属于内核启动参数的内容被当成QEMU的独立命令行参数,QEMU因此尝试把nokaslr当作文件打开,最终报错。
正确的做法是用bash数组保存参数,数组会保留每个参数的边界,不会错误拆分空格:
# 用数组保存内核相关参数 KERNEL_CFG=( -kernel Image -append "root=/dev/vda1 nokaslr console=ttyAMA0 earlycon=pl011,mmio,0x09000000" ) # 用数组保存磁盘相关参数 DISK_CFG=( -drive "if=none,file=$DISKFILE,format=qcow2,id=hd1" -device "virtio-blk-pci,drive=hd1,bootindex=0" ) # 执行QEMU时,用数组展开语法传递参数 sudo ./qemu-system-aarch64 \ -machine virt -cpu host -accel kvm \ -bios QEMU_EFI.fd \ -nographic \ -net user,hostfwd=tcp::2222-:22 -net nic \ -smp cpus=8 \ -m 4G \ "${KERNEL_CFG[@]}" \ "${DISK_CFG[@]}"
原理说明
- 数组的每个元素对应一个完整的QEMU参数(包括
-append后带空格的内核启动参数,整体作为数组的一个元素) "{数组名[@]}"展开时,shell会把数组每个元素作为独立命令行参数传递,完全保留元素内部的空格和引号,不会错误拆分。
如果想让脚本更简洁,也可以把所有参数写入同一个数组:
QEMU_ARGS=( -machine virt -cpu host -accel kvm -bios QEMU_EFI.fd -nographic -net user,hostfwd=tcp::2222-:22 -net nic -smp cpus=8 -m 4G -kernel Image -append "root=/dev/vda1 nokaslr console=ttyAMA0 earlycon=pl011,mmio,0x09000000" -drive "if=none,file=$DISKFILE,format=qcow2,id=hd1" -device "virtio-blk-pci,drive=hd1,bootindex=0" ) sudo ./qemu-system-aarch64 "${QEMU_ARGS[@]}"
内容的提问来源于stack exchange,提问作者peng6662001
相关产品推荐
相关产品推荐

