用于克隆活动 Ubuntu 分区的 Bash 脚本

用于克隆活动 Ubuntu 分区的 Bash 脚本

Ubuntu 18.04于 2018 年 4 月 26 日发布,我想尝试它来升级我的程序并转换我的数据,但如果有错误,我不想提交。

我将 Windows 从 410 GB 缩减到 385 GB,重新启动 Ubuntu 16.04,然后运行gparted创建一个新的 25 GB 分区,标记为“Ubuntu18.04”。我运行rm-kernels并删除了大约 20 个内核,以消除 Ubuntu 16.04 上的大约 10 GB。

现在我想要一个脚本,它将用 16.04 LTS 填充新分区并为其创建一个新的 Grub 菜单选项。只应复制相关目录。例如/sys/run/proc/dev在启动期间创建的虚拟目录,不应复制。

我还希望/etc/fstab使用正确的 UUID 进行修补并cron禁用重新启动作业,以便在启动克隆后不会运行克隆数据的每日备份。

我预计在接下来的几周/几个月内会多次运行该脚本。因此克隆过程应该可以轻松重复。

相同的脚本可用于测试安全更新和新的 Ubuntu Kernel Team 更新,而不会影响生产系统。

答案1

用于克隆活动 Ubuntu 分区的 Bash 脚本

bash脚本clone-ubuntu.sh将无缝且安全地将 16.04 LTS 复制到用于升级到 18.04 LTS 的分区中:

克隆-ubuntu.png

需要考虑的重要事项:

  • 必须创建一个ext4足够大的空分区来容纳Ubuntu 16.04 克隆
  • 调用脚本时clone-ubuntu.sh分区不能挂载。脚本会自动挂载和卸载分区。
  • 该命令rsync用于将文件从/克隆分区复制到克隆分区。第一次运行clone-ubuntu.sh该命令需要几分钟时间。第二次运行该脚本时,只会更新文件更改,并且运行时间应该不到一分钟。
  • 您可以运行此脚本并重新启动多次。任何新数据在克隆目标上将删除镜像当前/文件和目录。
  • 所有 Cron /etc/cron.d(重启)任务都移动到了名为 的新子目录/etc/cron.d/hold。启动克隆后记得运行sudo crontab -e以防止选定的 cron 任务运行。
  • 克隆的文件/etc/fstab将使用其所在分区的适当 UUID 进行修改。
  • 克隆文件/boot/grub/grub.cfg会使用适当的 UUID 进行修改,以便成功启动克隆文件。克隆文件的 UUIDquiet splash会更改为,nosplash以便您获得滚动终端消息。这让您直观地了解启动的是克隆版本,而不是“真实”版本。
  • update-grub运行以使用指向克隆分区的新菜单选项来更新 Grub。
  • 克隆的文件/etc/update-manager/release-upgrades被修改为Prompt=neverPrompt=lts当您启动克隆并执行do-release-upgrade -d此操作时,可以将 Ubuntu 16.04 升级到 18.04。
  • 克隆之前会显示一个确认屏幕(显示在下一部分中),您必须输入 y/Y 才能继续。

确认屏幕

选择目标克隆分区后,首先会验证其ext4分区类型,并且尚未安装。如果此测试通过,则会出现一条确认消息:

=====================================================================
Mounting clone partition /dev/nvme0n1p8 as /mnt/clone16.04

=====================================================================
PLEASE: Carefully confirm Source (Live) and Target (Clone) partitions

SOURCE (BOOT /):  /dev/nvme0n1p5      TARGET (CLONE):  /dev/nvme0n1p8
ID:               Ubuntu              ID:              Ubuntu
RELEASE:          16.04               RELEASE:         16.04
CODENAME:         xenial              CODENAME:        xenial
DESCRIPTION:      Ubuntu 16.04.3 LTS  DESCRIPTION:     Ubuntu 16.04.3 LTS
 Size  Used Avail Use%                 Size  Used Avail Use%
  44G   17G   26G  40%                  24G   17G  5.8G  74%

NOTE: If you are recloning, new files in clone will be deleted,
      modified files are reset to current source content and,
      files deleted from clone are added back from source.

Type Y (or y) to proceed. Any other key to exit: 

在此示例中,已选择先前的克隆进行重新克隆。克隆上的可用空间是静音点,因为我们已经知道有足够的可用空间。

如果您有多个 Ubuntu 安装,请确认您已选择正确的分区来克隆当前启动的 Ubuntu(以/(根)身份安装)。

y这是您最后一次机会,可以通过按或以外的任意键来中止Y


输出列表

运行脚本时,您将获得以下输出(不包括上面已列出的输出):

=====================================================================
Using rsync to clone / to /dev/nvme0n1p8 mounted as /mnt/clone16.04
          6.11G  38%   86.46MB/s    0:01:07 (xfr#139123, to-chk=0/647700)   

Number of files: 647,700 (reg: 470,100, dir: 104,694, link: 72,903, special: 3)
Number of created files: 127,824 (reg: 72,472, dir: 15,825, link: 39,526, special: 1)
Number of deleted files: 73,318 (reg: 59,766, dir: 9,701, link: 3,847, special: 4)
Number of regular files transferred: 139,123
Total file size: 15.92G bytes
Total transferred file size: 6.11G bytes
Literal data: 6.11G bytes
Matched data: 0 bytes
File list size: 8.50M
File list generation time: 0.001 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 6.14G
Total bytes received: 7.82M

sent 6.14G bytes  received 7.82M bytes  89.74M bytes/sec
total size is 15.92G  speedup is 2.59

Time to clone files: 68 Seconds

=====================================================================
Making changes in: /mnt/clone16.04/etc/update-manager/release-upgrades
     from Prompt=: never
       to Prompt=: lts
Allows running 'do-release-upgrade -d' when rebooting clone target
Consider 'do-release-upgrade -d -f DistUpgradeViewNonInteractive' This
allows you to go to bed or go to lunch whilst upgrade runs.

* * *  When you Upgrade, TURN OFF screen locking for inactivity. * * *

=====================================================================
Making changes in: /mnt/clone16.04/etc/fstab
        from UUID: f3f8e7bc-b337-4194-88b8-3a513f6be55b
          to UUID: 113f9955-a064-4ce2-9cae-74f2a9518550

=====================================================================
Making changes in: /mnt/clone16.04/boot/grub/grub.cfg
        from UUID: f3f8e7bc-b337-4194-88b8-3a513f6be55b
          to UUID: 113f9955-a064-4ce2-9cae-74f2a9518550
Also change 'quiet splash' to 'nosplash' for environmental awareness
Suggest first time booting clone you make wallpaper unique

=====================================================================
Calling 'update-grub' to create new boot menu
Generating grub configuration file ...
Found background: /home/rick/Pictures/1600x900/21.jpg
Found background image: /home/rick/Pictures/1600x900/21.jpg
Found linux image: /boot/vmlinuz-4.14.34-041434-generic
Found initrd image: /boot/initrd.img-4.14.34-041434-generic
Found linux image: /boot/vmlinuz-4.14.31-041431-generic
Found initrd image: /boot/initrd.img-4.14.31-041431-generic
Found linux image: /boot/vmlinuz-4.14.30-041430-generic
Found initrd image: /boot/initrd.img-4.14.30-041430-generic
Found linux image: /boot/vmlinuz-4.14.27-041427-generic
Found initrd image: /boot/initrd.img-4.14.27-041427-generic
Found linux image: /boot/vmlinuz-4.14.15-041415-generic
Found initrd image: /boot/initrd.img-4.14.15-041415-generic
Found linux image: /boot/vmlinuz-4.14.10-041410-generic
Found initrd image: /boot/initrd.img-4.14.10-041410-generic
Found linux image: /boot/vmlinuz-4.14.4-041404-generic
Found initrd image: /boot/initrd.img-4.14.4-041404-generic
Found linux image: /boot/vmlinuz-4.14.2-041402-generic
Found initrd image: /boot/initrd.img-4.14.2-041402-generic
Found linux image: /boot/vmlinuz-4.13.9-041309-generic
Found initrd image: /boot/initrd.img-4.13.9-041309-generic
Found linux image: /boot/vmlinuz-4.10.0-42-generic
Found initrd image: /boot/initrd.img-4.10.0-42-generic
Found linux image: /boot/vmlinuz-4.9.77-040977-generic
Found initrd image: /boot/initrd.img-4.9.77-040977-generic
Found linux image: /boot/vmlinuz-4.4.0-104-generic
Found initrd image: /boot/initrd.img-4.4.0-104-generic
Found linux image: /boot/vmlinuz-3.16.53-031653-generic
Found initrd image: /boot/initrd.img-3.16.53-031653-generic
Found Windows Boot Manager on /dev/nvme0n1p2@/EFI/Microsoft/Boot/bootmgfw.efi
Found Ubuntu 16.04.3 LTS (16.04) on /dev/nvme0n1p8
Found Windows Boot Manager on /dev/sda1@/efi/Microsoft/Boot/bootmgfw.efi
Adding boot menu entry for EFI firmware configuration
done

=====================================================================
Unmounting /dev/nvme0n1p8 as /mnt/clone16.04

rsync新克隆的状态显示

首次克隆时,rsync将更新所有创建的文件,更新内容从 0 到 100%。由于克隆为空,因此不会删除或更改任何文件:

clone-ubuntu.sh 空 clone.gif

rsync重新克隆时的状态显示

rsync重新克隆时不会发生任何100%错误,因为从未更改的文件不会被复制。更新进度会有所延迟,因为需要rsync扫描下一个要复制的文件,并且会删除在克隆中创建但原始文件中不存在的新文件:

克隆-ubuntu-rsync.gif


Bash 脚本 -clone-ubuntu.sh

#!/bin/bash

# NAME: clone-ubuntu.sh
# PATH: /usr/local/bin
# DESC: Written for AU Q&A: https://askubuntu.com/questions/1028604/bash-seemless-safe-script-to-upgrade-16-04-to-18-04/1028605#1028605
# DATE: Apr 27, 2018. Modified May 6, 2018.

# UPDT: May 02 2018 - Display selected parition and get confirmation.
#       May 06 2018 - Revise `do-release-upgrade -d` instructions.
#                     Correct listing of files in empty target partition.
#       Aug 09 2018 - Add --inplace parameter to `rsync`
#                     Comment out disabling `/etc/cron.d` on clone target.
#                     Users may uncomment and/or revise to their needs.

# $TERM variable may be missing when called via desktop shortcut
CurrentTERM=$(env | grep TERM)
if [[ $CurrentTERM == "" ]] ; then
    notify-send --urgency=critical \ 
                "$0 cannot be run from GUI without TERM environment variable."
    exit 1
fi

# Must run as root
if [[ $(id -u) -ne 0 ]] ; then echo "Usage: sudo $0" ; exit 1 ; fi

#
# Create unqique temporary file names
#

tmpPart=$(mktemp /tmp/clone-ubuntu.XXXXX)   # Partitions list
tmpMenu=$(mktemp /tmp/clone-ubuntu.XXXXX)   # Menu list
tmpInf1=$(mktemp /tmp/clone-ubuntu.XXXXX)   # Soucre (Booted) Ubuntu Info
tmpInf2=$(mktemp /tmp/clone-ubuntu.XXXXX)   # Target (Cloned) Ubuntu Info
tmpInf3=$(mktemp /tmp/clone-ubuntu.XXXXX)   # Work file used by DistInfo ()

#
# Function Cleanup () Removes temporary files
#

CleanUp () {
    [[ -f "$tmpPart" ]] && rm -f "$tmpPart" # If we created temp files
    [[ -f "$tmpMenu" ]] && rm -f "$tmpMenu" #  at various program stages
    [[ -f "$tmpInf1" ]] && rm -f "$tmpInf1" #  then remove them before
    [[ -f "$tmpInf2" ]] && rm -f "$tmpInf2" #  exiting.
    [[ -f "$tmpInf3" ]] && rm -f "$tmpInf3"

    if  [[  -d "$TargetMnt" ]]; then        # Did we create a clone mount?
        umount "$TargetMnt" -l              # Unmount the clone
        rm  -d "$TargetMnt"                 # Remove clone directory
    fi
}

#
# Function GetUUID () gets UUIDs of source and clone target partitions in menu.
#

GetUUID () {

    SrchLine="$1"                           # menu line passed to function
    UUID_col=0                              # start column of UUID in line
    lsblk -o NAME,UUID > "$tmpPart"         # Get list of UUID's

    while read -r UUID_Line; do             # Read through UUID list

        # Establish UUID position on line
        if [[ $UUID_col == 0 ]] ; then      # First time will be heading
            UUID_col="${UUID_Line%%UUID*}"  # Establish column number
            UUID_col="${#UUID_col}"         #  where UUID appears on line
            NameLen=$(( UUID_col - 1 ))     # Max length of partition name
            continue                        # Skip to read next line
        fi

        # Check if Passed line name (/dev/sda1, /nvme01np8, etc.) matches.
        if [[ "${UUID_Line:0:$NameLen}" == "${SrchLine:0:$NameLen}" ]] ; then
            FoundUUID="${UUID_Line:UUID_col:999}"
            break                           # exit function
        fi

    done < "$tmpPart"                       # Read next line & loop back
}


#
# Function DistInfo () builds information about source & target partitions
#

DistInfo () {

    Mount="$1"                              # Mount name is '/' or $TargetMnt
    FileName="$2"                           # "$tmpInf1" or "$tmpInf2" work file
    cat "$Mount"/etc/lsb-release >> "$FileName"
    sed -i 's/DISTRIB_//g' "$FileName"      # Remove DISTRIB_ prefix.
    sed -i 's/=/:=/g' "$FileName"           # Change "=" to ":="
    sed -i 's/"//g' "$FileName"             # Remove " around "Ubuntu 16.04...".

    # Align columns from "Xxxx:=Yyyy" to "Xxxx:      Yyyy"
    cat "$FileName" | column -t -s '=' > "$tmpInf3"
    cat "$tmpInf3" > "$FileName"
}


#
# Mainline
#

lsblk -o NAME,FSTYPE,LABEL,SIZE,MOUNTPOINT > "$tmpMenu"

i=0
SPACES='                                                                     '
DoHeading=true
AllPartsArr=()      # All partitions.

# Build whiptail menu tags ($i) and text ($Line) into array

while read -r Line; do
    if [[ $DoHeading == true ]] ; then
        DoHeading=false                     # First line is the heading.
        MenuText="$Line"                    # Heading for whiptail.
        FSTYPE_col="${Line%%FSTYPE*}"           
        FSTYPE_col="${#FSTYPE_col}"         # Required to ensure `ext4`.
        MOUNTPOINT_col="${Line%%MOUNTPOINT*}"
        MOUNTPOINT_col="${#MOUNTPOINT_col}" # Required to ensure not mounted.
        continue
    fi

    Line="$Line$SPACES"                     # Pad extra white space.
    Line=${Line:0:74}                       # Truncate to 74 chars for menu.

    if [[ "${Line:MOUNTPOINT_col:4}" == "/   " ]] ; then
        GetUUID "$Line"
        SourceUUID=$FoundUUID
        # Build "/dev/Xxxxx" FS name from "├─Xxxxx" lsblk line
        SourceDev="${Line%% *}"
        SourceDev=/dev/"${SourceDev:2:999}"
    fi

    AllPartsArr+=($i "$Line")               # Menu array entry = Tag# + Text.
    (( i++ ))

done < "$tmpMenu"                           # Read next "lsblk" line.

#
# Display whiptail menu in while loop until no errors, or escape,
# or valid partion selection .
#

DefaultItem=0

while true ; do

    # Call whiptail in loop to paint menu and get user selection
    Choice=$(whiptail \
        --title "Use arrow, page, home & end keys. Tab toggle option" \
        --backtitle "Clone 16.04 for upgrade.  ONLY CLONES / PARTITION" \
        --ok-button "Select unmounted partition" \
        --cancel-button "Exit" \
        --notags \
        --default-item "$DefaultItem" \
        --menu "$MenuText" 24 80 16 \
        "${AllPartsArr[@]}" \
        2>&1 >/dev/tty)

    clear                                   # Clear screen.
    if [[ $Choice == "" ]]; then            # Escape or dialog "Exit".
        CleanUp
        exit 0;
     fi

    DefaultItem=$Choice                     # whiptail start option.
    ArrNdx=$(( $Choice * 2 + 1))            # Calculate array offset.
    Line="${AllPartsArr[$ArrNdx]}"          # Array entry into $Line.

    # Validation - Don't wipe out Windows or Ubuntu 16.04:
    # - Partition must be ext4 and cannot be mounted.

    if [[ "${Line:FSTYPE_col:4}" != "ext4" ]] ; then
        echo "Only 'ext4' partitions can be clone targets."
        read -p "Press <Enter> to continue"
        continue
    fi

    if [[ "${Line:MOUNTPOINT_col:4}" != "    " ]] ; then
        echo "A Mounted partition cannot be a clone target."
        read -p "Press <Enter> to continue"
        continue
    fi

    GetUUID "$Line"                         # Get UUID of target partition.
    TargetUUID=$FoundUUID

    # Build "/dev/Xxxxx" FS name from "├─Xxxxx" menu line
    TargetDev="${Line%% *}"
    TargetDev=/dev/"${TargetDev:2:999}"

    break                                   # Validated: Break menu loop.

done                                        # Loop while errors.

#
# Mount Clone Target partition
#

Release=$(lsb_release -rs)                  # Source version ie: '16.04'
TargetMnt="/mnt/clone$Release"

echo ""
echo "====================================================================="
echo "Mounting clone partition $TargetDev as $TargetMnt"
mkdir -p "$TargetMnt"                       # '-p' directory may already exist
mount -t auto -v $TargetDev "$TargetMnt" > /dev/null

# Confirm partition is empty. If not empty confirm it's Ubuntu. If not exit.
# If Ubuntu display prompt with the version it contains and get confirmation.

echo ""
echo "====================================================================="
echo "PLEASE: Carefully confirm Source (Live) and Target (Clone) partitions"

# Build source information (our current boot partition)
echo "SOURCE (BOOT /)=$SourceDev"  > "$tmpInf1"
DistInfo "/" "$tmpInf1"                     # /etc/lsb_release information
df -h --output=size,used,avail,pcent "$SourceDev" >> "$tmpInf1"

# Build target information (the partition selected for cloning to)
LineCnt=$(ls "$TargetMnt" | wc -l)
if (( LineCnt > 1 )) ; then 
    # More than /Lost+Found exist so it's not an empty partition.
    if [[ -f "$TargetMnt"/etc/lsb-release ]] ; then
        echo "TARGET (CLONE)=$TargetDev" > "$tmpInf2"
        DistInfo "$TargetMnt" "$tmpInf2"    # /etc/lsb_release information
    else
        # TO-DO: might be cloning /boot or /home on separate partitions.
        #        the source partition is still `/` so can display message.
        echo "Selected partition has data which is not Ubuntu OS. Aborting."
        CleanUp                             # Remove temporary files
        exit 1
    fi
else
    echo "Target (Clone) partition appears empty" > "$tmpInf2"
    echo "/Lost+Found normal in empty partition" >> "$tmpInf2"
    echo "Head of '/Clone/' files & directories:" >> "$tmpInf2"
    ls "$TargetMnt" | head -n2 >> "$tmpInf2"
fi

# Target device free bytes
df -h --output=size,used,avail,pcent "$TargetDev" >> "$tmpInf2"

# Display source and target partitions side-by-side using bold text.
echo $(tput bold)       # Set to bold text
paste -d '|' "$tmpInf1" "$tmpInf2" | column -t -s '|'
echo $(tput sgr0)       # Reset to normal text

echo "NOTE: If you are recloning, new files in clone will be deleted,"
echo "      modified files are reset to current source content and,"
echo "      files deleted from clone are added back from source."
echo ""

read -p "Type Y (or y) to proceed. Any other key to exit: " -n 1 -r
echo    # (optional) move to a new line
if [[ ! $REPLY =~ ^[Yy]$ ]] ; then
    CleanUp             # Remove temporary files
    exit 0
fi

# Copy non-virtual directories to clone. Credit to TikTak's Ask Ubuntu answer:
# https://askubuntu.com/questions/319805/is-it-safe-to-clone-the-current-used-disk?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa

SECONDS=0
echo ""
echo "====================================================================="
echo "Using rsync to clone / to $TargetDev mounted as $TargetMnt"
rsync -haxAX --stats --delete --info=progress2 --info=name0 --inplace  \
      /* "$TargetMnt"                                                   \
      --exclude={/dev/*,/proc/*,/sys/*,/tmp/*,/run/*,/mnt/*,/media/*,/lost+found}
# For 16GB on Samsung Pro 960: First time 98 seconds, second time 27 seconds.
rsyncTime=$SECONDS  
echo ""
echo "Time to clone files: $rsyncTime Seconds"

# Change /etc/update-manager/release-upgrades prompt from never to LTS
echo ""
echo "====================================================================="
echo "Making changes in: $TargetMnt/etc/update-manager/release-upgrades"
echo "     from Prompt=: never"
echo "       to Prompt=: lts"
echo "Allows running 'do-release-upgrade -d' when rebooting clone target"
echo "Consider 'do-release-upgrade -d -f DistUpgradeViewNonInteractive' This"
echo "allows you to go to bed or go to lunch whilst upgrade runs."
echo ""
echo "* * *  When you Upgrade, TURN OFF screen locking for inactivity. * * *"
echo ""
sed -i 's/Prompt=never/Prompt=lts/' "$TargetMnt"/etc/update-manager/release-upgrades

## This section commented out to prevent surprises. You may uncomment.
## You may want to revise to include `cron.daily`, `cron.hourly`, etc.
# Move `/etc/cron.d` reboot jobs to `/etc/cron.d/hold` to prevent running
# scripts such as daily backup or Ubuntu 16.04 specific problem fixes.
#echo ""
#echo "====================================================================="
#echo "Moving '$TargetMnt/etc/cron.d' to '.../hold' to prevent running."
#echo "After booting clone, move back individual files you want to run"
#if [[ ! -d "$TargetMnt"/etc/cron.d/hold ]]; then
#    mkdir "$TargetMnt"/etc/cron.d/hold
#fi
#cp -p  "$TargetMnt"/etc/cron.d/* "$TargetMnt"/etc/cron.d/hold/
#rm -fv "$TargetMnt"/etc/cron.d/*

# Update /etc/fstab on clone partition with clone's UUID
echo ""
echo "====================================================================="
echo "Making changes in: $TargetMnt/etc/fstab"
echo "        from UUID: $SourceUUID"
echo "          to UUID: $TargetUUID"
sed -i "s/$SourceUUID/$TargetUUID/g" "$TargetMnt"/etc/fstab

# Update /boot/grub/grub.cfg on clone partition with clone's UUID
echo ""
echo "====================================================================="
echo "Making changes in: $TargetMnt/boot/grub/grub.cfg"
echo "        from UUID: $SourceUUID"
echo "          to UUID: $TargetUUID"
echo "Also change 'quiet splash' to 'nosplash' for environmental awareness"
echo "Suggest first time booting clone you make wallpaper unique"
sed -i "s/$SourceUUID/$TargetUUID/g" "$TargetMnt"/boot/grub/grub.cfg
sed -i "s/quiet splash/nosplash/g" "$TargetMnt"/boot/grub/grub.cfg

# Update grub boot menu
echo ""
echo "====================================================================="
echo "Calling 'update-grub' to create new boot menu"
update-grub

# Unmount and exit

echo ""
echo "====================================================================="
echo "Unmounting $TargetDev as $TargetMnt"

CleanUp             # Remove temporary files

exit 0

将上面的 bash 代码复制并粘贴到名为 的新文件中/usr/local/bin/clone-ubuntu.sh。然后使用以下命令使新文件可执行:

sudo chmod a+x /usr/local/bin/clone-ubuntu.sh

要调用脚本,请使用:

sudo clone-ubuntu.sh

如何将 16.04 LTS 克隆版本升级到 Ubuntu 18.04 LTS

这是一个可能引起很多人感兴趣的“奖励”部分。

重启机器。grub菜单将包含一个指向克隆分区的新菜单选项。您还可以从克隆的高级选项菜单。

将克隆的 16.04 LTS 转换为 18.04 LTS 的一种方法是运行:

sudo do-release-upgrade

请注意,该-d标志在 2018 年 7 月 26 日之前是必需的,但现在不再需要。

仔细阅读 18.04 升级确认

继续操作之前,请确保非活动屏幕锁定已关闭。如果由于键盘不活动而导致计算机进入锁定屏幕,升级过程可能会崩溃。

18.04升级过程总结

本节将针对特定机器,因为不同的用户会安装不同的应用程序。以下是我根据笔记和记忆做出的简要总结:

  1. 确认继续:ENTER
  2. 软件包将被删除:Y
  3. 替换 longind.conf: Y
  4. 配置文件 '/etc/sane.d/dll.conf',默认 N,取 Y
  5. '/etc/NetworkManager/conf.d/default-wifi-powersave-on.conf' 采用默认 N
  6. 配置文件 '/etc/pulse/default.pa' 默认N,取Y
  7. 配置文件‘/etc/grub.d/30_os-prober’默认N,取N
  8. 出现全屏 grub 菜单配置。选择:保留当前安装的本地版本
  9. 配置文件'/etc/cron.d/anacron',默认N,取Y看看
  10. 多次出现错误信息:/sbin/ldconfig.real: 警告:忽略无法打开的配置文件:/etc/ld.so.conf.d/x86_64-linux-gnu_EGL.conf: 没有此文件或目录
  11. 非标准:配置文件“/etc/vnstat.conf”(显示差异 1.13 与 1.18)取 Y
  12. 220 个包将被删除。(可能需要几个小时)输入 Y
  13. 要完成升级,需要重新启动。选择 Y

注意大多数人永远不会看到第 10 步。我的 Ubuntu 16.04 上有一个旧的 nVidia 驱动程序安装,我从来没有完全删除过。之所以包含它,是因为您可能有类似的旧软件包从未完全删除过。

Grub 更改启动菜单以在 UEFI 下克隆

与 18.04 升级不同,我发现 18.04.1 升级改变了 Grub UEFI 配置,以使用克隆的 grub 菜单而不是原始 grub 菜单,如以下答案所述:双重启动和文件 /boot/grub/grub.cfg ——使用哪一个?

$ sudo cat /boot/efi/EFI/ubuntu/grub.cfg
search.fs_uuid b40b3925-70ef-447f-923e-1b05467c00e7 root 
set prefix=($root)'/boot/grub'
configfile $prefix/grub.cfg

$ sudo grub-install
Installing for x86_64-efi platform.
Installation finished. No error reported.

启动原始分区后运行sudo update-grub不足以改变grub.cfggrub 加载的内容。您需要使用sudo grub-install强制 grub 使用原始分区的配置。

原始分区和克隆分区均可用于update-grub维护自己的/boot/grub/grub.cfg文件,但在启动时只能使用一个。

当然如果您希望 grub 使用克隆的 grub 菜单请不要在原始分区上执行上述步骤。


編輯歷史

编辑于 2018 年 5 月 6 日- 更正了空克隆(目标)分区的信息显示。

编辑于 2018 年 8 月 26 日- 使用--inplace选项,rsync在复制过程中,克隆时不会复制 2 GB 的垃圾文件等大文件。这可能会导致“磁盘空间不足”错误。注释掉/etc/cron.d覆盖,因为用户可能想要保留或想要一个完全不同的目录。更新说明以使用do-release-upgrade-d标记,因为 Ubuntu 18.04.1 LTS 现已发布。

答案2

从以前的版本升级到 18.04 LTS 时出现的问题

从以前的版本升级到 18.04 LTS 一点也不简单。我不知道过去是否有比这种升级更多的问题,但是现在进行版本升级的人要承担风险一方面,他们发现 bug 并如果有错误被报告,将有助于开发升级工具以及调试Ubuntu 18.04 LTS系统本身。

这意味着有足够耐心的人等待升级正式发布第一个版本(18.04.1 LTS)将会更加顺畅

进行全面升级之前进行测试...

@WinEunuuchs2Unix 在此处描述的方法可以使用真实系统的副本进行测试,看看升级到 18.04 LTS 是否可以与您当前的 [或多或少经过修改的] 操作系统和您的计算机硬件兼容。

这可以防止因操作系统损坏而导致的多种灾难。

我还没有使用过@WinEunuuchs2Unix 的脚本,但我知道它非常有用,我打算使用它。我能够从 8.04 升级到 10.04 再到 12.04,我已经使用了很长时间。但当我打算从 14.04 升级到 16.04 时,我失败了,找不到错误。

...如果出现问题,请重新安装

我有良好的备份,所以我重新安装了 16.04,然后复制了我想保留的内容,并检查了调整、脚本、别名和已安装的程序。如果我使用 @WinEunuuchs2Unix 的方法,我早就发现了问题,我会直接重新安装。

升级持久实时系统

持久实时系统用于获得高度可移植的 Ubuntu 系统,有时用于测试,但有时会使用很长时间。

一个众所周知的问题就是,您不应该像安装系统那样更新和升级此类系统,因为它迟早会被损坏。此外,您只能使用 iso 文件附带的内核和内核驱动程序,因为它们在覆盖系统启动之前就已启动。

但是通常可以保留/home目录,就像您在使用单独的“主”分区进行全新安装时所做的那样。如果您创建分区home-rw,持久实时系统将在启动期间自动找到并使用它。

我正在开发和测试一个 shellscript,mk-persistent-live_with_home-rw可以创造具有分区的持久实时系统home-rw,以及可以稍后升级它,

  • 用较新的 iso 文件替换该 iso 文件。至少在发布新的 iso 文件时您应该升级,但您也可以每月升级一次 LTS 系统,并使用当前的每日 iso 文件测试追踪器

  • 修改 grub 以适应新的 iso 文件。

  • 擦除(重新格式化)casper-rw存储操作系统修改的文件(因此您必须重新安装添加到系统中的程序包),

  • 保存home-rw包含您的个人文件、设置和调整的分区。

  • 此链接更多细节。

附加链接

对于想要测试最新和最好的 Ubuntu 版本的人来说,可以在以下链接中找到一般提示,

如何参与 Ubuntu 的测试和开发

相关内容