如何通过命令行创建USB安装器以安装Ubuntu?

我正在尝试创建一个可启动的USB镜像,以便在一台新电脑上安装Ubuntu。

之前我按照Ubuntu桌面版的"创建USB驱动器"指南做过这个,但现在我没有可用的Ubuntu桌面版。

我该如何只使用命令行来完成同样的操作?

我尝试过的方法:

在Mac OS X上按照ubuntu.com的“创建USB驱动器”说明创建可启动的USB:无法启动。 usb-creator:根据apt-cache search usb-creator和维基百科,usb-creator只存在作为图形工具。 在help.ubuntu.com上的"手动创建"说明中:ISO映像中没有描述的文件和目录(例如casperfilesystem.manifestmenu.lst),我不知道它们被替换成了什么。 unetbootin脚本:即使完全脚本化,也需要X服务器(图形支持)才能运行。(命令sudo unetbootin lang=en method=diskimage isofile=~/ubuntu-10.10-server-amd64.iso installtype=USB targetdrive=/dev/sdg1 autoinstall=yes会显示错误信息unetbootin: cannot connect to X server。)

更新

还尝试了GRUB的调整:从以下来源整合信息:

我成功地进行了一半的操作 - 它从USB启动,显示了grub菜单并开始安装,但是安装没有完成。

供参考,这是我最接近成功的情况:

sudo su
  # mount USB pen
mount /dev/sd[X]1 /media/usb
  # install GRUB
grub-install --force --no-floppy --root-directory=/media/usb /dev/sd[X]
  # copy ISO image to USB
cp ~/ubuntu-10.10-server-amd64.iso /media/usb
  # mount ISO image, copy existing grub.cfg
mount ~/ubuntu-10.10-server-amd64.iso /media/iso/ -o loop
cp /media/iso/boot/grub/grub.cfg /media/usb/boot/grub/

我然后编辑了/media/usb/boot/grub.cfg,添加了一个.iso循环回环的例子grub条目。
menuentry "Install Ubuntu Server" {
  set gfxpayload=keep
  loopback loop /ubuntu-10.10-server-amd64.iso  
  linux (loop)/install/vmlinuz  file=(loop)/preseed/ubuntu-server.seed iso-scan/filename=/ubuntu-10.10-server-amd64.iso quiet --
  initrd (loop)/install/initrd.gz
}

当从USB启动时,这会给我Grub引导菜单并启动安装程序,但安装程序在几个屏幕后放弃了,并抱怨找不到光驱。(当然,因为我要安装的机器没有光驱。)
我通过放弃并使用Ubuntu Live桌面CD(在一台有光驱的计算机上)进行“创建USB驱动器”例程来解决了这个特定问题,然后USB安装就可以工作了。
但我希望在没有X服务器和光驱的Ubuntu系统的命令行中有某种方法来做到这一点,所以问题仍然存在。
有人知道如何吗?

试试unetbootin。 - RolandiXor
@Roland unetbootin: 无法连接到X服务器 - 即使在完全脚本化的情况下(unetbootin lang=en method=diskimage isofile=/srv/share/ubuntu-10.10-server-amd64.iso installtype=USB targetdrive=/dev/sdg1 autoinstall=yes),似乎仍需要X,并且我更倾向于保持无头状态。谢谢你的建议,不过如果没有其他选择了,我可能会安装X。 - j-g-faustus
这些看起来很有希望:http://www.pendrivelinux.com/install-grub2-on-usb-from-ubuntu-linux/ 和 http://unix.stackexchange.com/questions/665/installing-grub-2-on-a-usb-flash-drive 需要一些调整,但我会尝试它。 - j-g-faustus
@j-g-faustus:如果事情如此复杂,我可能会放弃Linux,也许使用 dd。它是一颗璀璨的宝石。难以言表。而且每个Linux发行版都有 dd;因此你拥有一个通用解决方案,无需编写脚本/配置。只需要一行美丽的命令。 - Mahesh
那个 grub.cfg 的条目需要在 linux 行上写成 file=/cdrom/preseed/ubuntu-server.seed(而不是 file=(loop)/preseed/ubuntu-server.seed),以避免在成功检测到 CD 镜像后出现致命的“无法检索预配置文件”的错误。 - Paul Whittaker
如果你正在使用备用安装映像(ubuntu-12.04-alternate-amd64.iso),那么你将无法找到ubuntu-server.seed文件;我改用了cli.seed,我相信它会产生与F4菜单中的“仅命令行安装”选项相同的结果。 - Paul Whittaker
还可以看看我在这里的回答(http://askubuntu.com/questions/781223/physical-block-size-is-2048-bytes-but-linux-says-it-is-512-when-formatting-a/781236#781236)- 这个问题更相关,因为它最初回答的问题有些迁移。 - Zanna
7个回答

你试过用 # dd if=path/to/image.iso of=/dev/sd# 这个命令了吗?

这个真是个宝贝。最好的一个。适用于任何Linux发行版。但你需要特别小心。添加bs=20M或其他合适的值可以加快速度。详细信息请参考man dd - Mahesh
1@Mahesh 不,有些Linux发行版即使使用这个命令也无法工作,其中之一就是OpenSUSE。 - Anwar
或者MeeGo及其衍生版本中,这些镜像被称为混合型的。 - rzr

从USB启动时,这会给我Grub引导菜单,并启动安装程序,但安装程序在几个屏幕后放弃了,并抱怨找不到CD-ROM驱动器。
这是一个已知的Ubuntu服务器ISO的错误(桌面版ISO正常运行),但有一个修复方法,可以从USB驱动器上获取ISO中的软件包: 一旦进入安装程序界面,按下Ctrl+Alt+f2打开终端,然后输入以下命令:
mount -t vfat /dev/sdX1 /mnt
ln -sf /mnt/ubuntu-server.iso /dev/sr0

然后切换回安装程序,并重新尝试扫描 CD 来获取软件包。应该可以工作。

我目前没有系统可以尝试,但是听起来应该可以工作 :) 谢谢! - j-g-faustus
我发现“检测和挂载CD-ROM”菜单选项会将/dev/sr0还原,撤销ln并将其恢复到原始(损坏)状态。但是,如果我在“重试挂载CD-ROM?”提示处等待,并在tty2中执行ln,然后返回按下“是”,它就会起作用。(这个“重试?”对话框只会在输入mount命令后出现。) - Paul Whittaker

假设你面前只有一个提示符。如果你有图形用户界面(GUI),你可以打开终端并按照这里描述的一切操作。或者你可以使用tty。
警告: 为了避免潜在的损害,请非常小心地按照说明进行操作。
切换到root提示符,输入sudo su。
检测USB设备是什么。 tail -f /var/log/syslog
现在你可以实时查看syslog。插入你的USB驱动器。屏幕上应该会显示一些消息。类似于这样。
May 27 00:35:07 Mahesh kernel: [ 5054.646585] usb 2-1.1: new high-speed USB device number 5 using ehci_hcd
May 27 00:35:07 Mahesh kernel: [ 5054.741437] scsi8 : usb-storage 2-1.1:1.0
May 27 00:35:07 Mahesh mtp-probe: checking bus 2, device 5: "/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.1"
May 27 00:35:07 Mahesh mtp-probe: bus: 2, device: 5 was not an MTP device
May 27 00:35:08 Mahesh kernel: [ 5055.739177] scsi 8:0:0:0: Direct-Access     JetFlash TS2GJFV30        8.07 PQ: 0 ANSI: 2
May 27 00:35:08 Mahesh kernel: [ 5055.740198] sd 8:0:0:0: Attached scsi generic sg3 type 0
May 27 00:35:08 Mahesh kernel: [ 5055.741593] sd 8:0:0:0: [sdc] 4005888 512-byte logical blocks: (2.05 GB/1.91 GiB)
May 27 00:35:08 Mahesh kernel: [ 5055.742214] sd 8:0:0:0: [sdc] Write Protect is off
May 27 00:35:08 Mahesh kernel: [ 5055.742218] sd 8:0:0:0: [sdc] Mode Sense: 03 00 00 00
May 27 00:35:08 Mahesh kernel: [ 5055.742712] sd 8:0:0:0: [sdc] No Caching mode page present
May 27 00:35:08 Mahesh kernel: [ 5055.742715] sd 8:0:0:0: [sdc] Assuming drive cache: write through
May 27 00:35:08 Mahesh kernel: [ 5055.745326] sd 8:0:0:0: [sdc] No Caching mode page present
May 27 00:35:08 Mahesh kernel: [ 5055.745329] sd 8:0:0:0: [sdc] Assuming drive cache: write through
May 27 00:35:08 Mahesh kernel: [ 5055.781564]  sdc: sdc1
May 27 00:35:08 Mahesh kernel: [ 5055.784191] sd 8:0:0:0: [sdc] No Caching mode page present
May 27 00:35:08 Mahesh kernel: [ 5055.784196] sd 8:0:0:0: [sdc] Assuming drive cache: write through
May 27 00:35:08 Mahesh kernel: [ 5055.784200] sd 8:0:0:0: [sdc] Attached SCSI removable disk

看一下,有没有方括号里面重复的东西?在这个例子中是sdc。把它记在一张纸上。按下Ctrl+C进入提示符。
找到要刻录到USB上的iso文件。
如果iso文件在/path/to/iso/somecd.iso;把这个路径记在一张纸上。
写入USB

警告:

这将会擦除整个USB磁盘。在继续之前备份。

  • dd if=/path/to/iso/somecd.iso of=/dev/sdc ibs=20M obs=20M
用实际的iso文件路径替换/path/to/iso/somecd.iso
用之前记下的内容替换/dev/sdc。如果重复部分是sdb,则使用/dev/sdb,依此类推。
警告: 输入错误的驱动器字母将导致不同驱动器上的数据永久丢失。在执行“dd”命令时要特别注意。

2为了避免因选择错误的磁盘而导致数据丢失,建议使用/dev/disk/by-label/LABEL而不是/dev/sdc - totti
1明智的建议。但是当你不确定标签,或者有很多“新卷”时,这就变得很麻烦了。我总是更喜欢sdX这个选项,但这只是个人选择。 - Mahesh
1最佳答案。一个建议的改进是在输入流上使用pv到dd,这样用户就可以得到进度反馈(即pv读取iso,将其流式传输到dd,并在stderr上显示进度)。 - Stabledog

使用终端创建可启动的Ubuntu USB闪存驱动器
  • ubuntu.iso文件挂载。在终端中运行以下命令:

    sudo mkdir /media/iso
    sudo mount -o loop /path/to/ubuntu.iso /media/iso
    
  • 然后将所有文件从/media/iso复制到您挂载的USB闪存驱动器文件夹中的/media

    插入您的USB闪存驱动器。

    每次插入时,它都会自动挂载。您的USB分区必须挂载在/media内。假设您的USB驱动器挂载在/media/xxxx文件夹中。然后运行以下命令:

    cp -a /media/iso/. /media/xxx
    

    运行lsblk命令以了解USB设备分区。

  • 然后将ldlinux.sys文件粘贴到您的USB闪存驱动器分区(在我的情况下是/dev/sdd1),以使其成为可引导的USB。运行以下命令:

    sudo apt-get install syslinux mtools
    syslinux -s /dev/sdd1
    
  • 进入/media/xxx文件夹,并将isolinux目录重命名为syslinux。然后进入重命名的syslinux文件夹,并将文件isolinux.cfg重命名为syslinux.cfg

       mv /media/xxx/isolinux /media/xxx/syslinux
       mv /media/xxx/syslinux/isolinux.cfg /media/xxx/syslinux/syslinux.cfg
    
  • 重新启动计算机并在BIOS中更改boot-order为USB。现在您的Ubuntu USB闪存驱动器将启动,您可以安装它。

这种方法适用于任何 Linux 发行版,不仅仅是 Ubuntu。


我通过使用Ubuntu Live桌面CD解决了这个特定的问题。
通过在带有光驱的计算机上启动Live CD,我可以使用Ubuntu桌面指南来创建USB闪存安装程序,而不会触及现有的安装。

你可以修改usb-creator来完成这个任务。
你的USB设备上应该已经有一个vfat分区,作为第一个分区(usb-creator-gtk的擦除磁盘步骤会自动创建这个分区),并且需要将其标记为可引导。
接下来,我们将使用usb-creator的Python代码来帮助我们。
$ sudo apt-get install usb-creator

或者

$ bzr branch lp:usb-creator

创建一个文件,内容为usb-creator-cli,并将其命名为usb-creator-cli。如果您在最后一步使用了bzr,请将此文件放置在usb-creator目录(bzr分支的根目录)中。
#!/usr/bin/env python
from __future__ import print_function
from usbcreator.misc import sane_path, setup_gettext, setup_logging, text_type

from usbcreator.install import install

sane_path()
setup_logging()
setup_gettext()

#/dev/sdb1 should be mounted on /mnt
#iso should be mounted to /iso
dev = '/dev/sdb1'
source = '/iso'
target = '/mnt' 
ugh = install(source, target, False, device=dev)
ugh.success = print
ugh.failure = print
ugh.progress = print
ugh.progress_message = print
ugh.progress_pulse = print
ugh.progress_pulse_stop = print
ugh.retry = print
ugh.run()

使其可执行
$ chmod +x usb-creator-cli

现在将您的ISO挂载到/iso,并将您的USB设备挂载到/mnt。
$ sudo mkdir /iso ; sudo mount ubuntu-server-12.10-amd64.iso /iso
$ sudo mount /dev/sdb1 /mnt

如果你想在控制台上看到非常详细的消息,你可以使用tail命令查看~/.cache/usb-creator.log文件。
$ tail -f ~/.cache/usb-creator.log &

现在运行usb-creator-cli脚本。
$ sudo ./usb-creator-cli

并观看所有消息滚动。

当您返回提示符时,请不要忘记在拔出USB存储设备之前卸载/mnt。



Crunchbang?哈哈? - RolandiXor
我没有问题将ISO文件放入这个U盘(它是16GB的),更多的是关于如何创建一个能够首先引导进入ISO文件的USB启动盘,而且只使用命令行界面来创建。 - j-g-faustus
很不幸,Unetbootin并不能正常工作 - 即使在命令行中运行它,似乎也需要图形支持。 - j-g-faustus