Compare commits

..

43 Commits

Author SHA1 Message Date
f2cfe672d1 windows: 修复查找 iso 功能失效
现在 massgrave 的 iso 链接 href="" 少了双引号
2026-01-18 18:51:37 +08:00
0cc3fc77d6 core: 避免有时 modloop 下载不完整导致报错
fixes #308 #370 #376
2026-01-08 22:33:44 +08:00
6a35bf681a ubuntu: 软件包不存在时才执行 apt install ,避免浪费时间更新 2026-01-08 22:33:43 +08:00
e7f8802bdd net: 修复天翼云电脑 udhcpc 不断尝试获取动态 IP
fixes #518
2026-01-08 22:33:43 +08:00
259bcf7275 windows: 适配 massgrave 新镜像链接 2026-01-07 23:10:09 +08:00
90becc9850 docs: 更新文档 2026-01-07 21:34:18 +08:00
85e2661161 windows: 使用更准确的 intel nic 驱动链接 2026-01-07 21:34:18 +08:00
74d9524a9b fnos: 优化飞牛安装
- 支持 bios + gpt
- 支持 arm
2026-01-07 21:34:17 +08:00
1a3d8b4f3b windows: 国内使用 daocloud 加速下载 win7 的 frpc 2025-12-30 00:18:04 +08:00
0c5fac6d6b ubuntu: 只禁用 cloud-init 而不是删除
fixes #516
2025-12-25 00:14:38 +08:00
e60a8d0de2 core: 修复 azure 开启加速网络时 NetworkManager 无法获取 IP
fixes #499
2025-12-04 22:56:16 +08:00
2a561f0d8c core: 添加 alpine 3.23, nixos 25.11 2025-12-04 19:43:54 +08:00
586eb5dee1 opensuse: 16.0 重新使用 cloud 镜像 2025-12-04 19:43:53 +08:00
c94f334663 core: 用 sh 运行时自动切换成 bash 2025-12-04 19:43:52 +08:00
bd5e118570 core: 修复 ECDSA-P521 设置报错 (#480)
fixes #479
2025-11-10 19:37:18 +08:00
78ba0690f9 windows: 添加 win8 链接 2025-11-04 22:17:11 +08:00
9e0968eabd windows: 从网页获取 intel vmd 驱动最新链接 2025-11-04 22:15:18 +08:00
3263ea3875 core: 改成使用 /dev/urandom 以修复生成随机密码时阻塞
fixes #469
fixes #471
2025-11-04 21:54:21 +08:00
7c19559d86 core: 日志显示使用缓冲区,避免卡顿 2025-10-31 07:50:45 +08:00
8b838f8871 core: 不重要的优化 2025-10-31 07:50:45 +08:00
5bf00edeed windows: 调整 intel nic 驱动
win7: 统一使用 25.0,即使镜像不支持 sha256,因为官网下架了旧版本驱动
win10: 不再固定版本,而是从网页获取最新版
2025-10-31 07:50:44 +08:00
85637edc5b windows: 优化镜像查找 2025-10-31 07:50:43 +08:00
baa430eb10 core: --frpc-toml 允许使用 http 链接 2025-10-31 07:50:43 +08:00
66f3173c7b core: alpine initrd 使用 udhcpc
dhcpcd 会配置租约时间,过期会移除 IP,但我们的没有在后台运行 dhcpcd ,因此用 udhcpc
2025-10-31 07:50:42 +08:00
af84ac0b3c core: 默认使用随机密码 2025-10-31 07:50:41 +08:00
57a88a6bd9 windows: 从注册表读取系统版本号
windows 10 22h2 版本号是 19045
但 exe 版本号是 19041
2025-10-31 07:50:41 +08:00
24a4446a02 debian: 支持在安装过程中开启 ssh 2025-10-31 07:50:40 +08:00
780e1a694f fedora: 添加 43 2025-10-29 00:06:54 +08:00
43ba86076f windows: 修复无法查找 win11 pro arm iso
fixes #460
2025-10-28 23:21:41 +08:00
f22cda1f10 opensuse: 添加 16.0 2025-10-18 23:41:24 +08:00
28e10128ff nixos: nix 版本号使用目标系统里面的,以修复 nixos-install 阶段报错
fixes #451
2025-10-17 20:57:27 +08:00
974d5712f0 debian: initrd 不精简 realtek 网卡驱动 2025-10-13 20:08:40 +08:00
845fa66e03 ubuntu: 添加 25.10 2025-10-11 00:01:19 +08:00
48823b4101 windows: 添加 GCP 兼容性说明 2025-10-11 00:01:18 +08:00
d212eb793c dd: 修复了用 wmic 获取网卡 id 时,!id! 变量保留了最后的 \r 导致语句不正确
fixes #444
fixes #445
fixes #446
2025-10-08 01:32:30 +08:00
aa1fc741fa Reapply "dd: 修复镜像没有 wmic 时无法配置静态 IP"
This reverts commit 74665b65cc.
2025-10-08 00:32:18 +08:00
74665b65cc Revert "dd: 修复镜像没有 wmic 时无法配置静态 IP"
This reverts commit 6708c77c63.
2025-10-07 02:58:20 +08:00
6708c77c63 dd: 修复镜像没有 wmic 时无法配置静态 IP 2025-10-05 23:35:36 +08:00
1afc1a0022 core: 通过文件判断分区作用 2025-10-02 00:10:24 +08:00
cdf09d017f openeuler: 修复 arm 机器进入了 grub rescue 模式
openeuler arm 25.09 云镜像里面的 grubaa64.efi 是用于 mbr 分区表,$root 是 hd0,msdos1
因此要重新下载 $root 是 hd0,gpt1 的 grubaa64.efi
2025-10-01 23:55:51 +08:00
8d55af091d windows: 更新 vmd 驱动 2025-09-29 22:12:25 +08:00
8689c45b07 ol: 添加 oracle linux 10 2025-09-29 21:00:08 +08:00
ce8a315a2e el: 修复 almalinux 9 链接 404
fixes #436
2025-09-21 15:27:17 +08:00
13 changed files with 1264 additions and 589 deletions

View File

@ -21,18 +21,19 @@ jobs:
git config --global core.autocrlf false git config --global core.autocrlf false
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- run: | - run: |
${{ matrix.command }} centos # ${{ matrix.command }} centos
${{ matrix.command }} almalinux 8 ${{ matrix.command }} almalinux
${{ matrix.command }} rocky 9 # ${{ matrix.command }} rocky
${{ matrix.command }} fedora # ${{ matrix.command }} fedora
# ${{ matrix.command }} oracle
${{ matrix.command }} ubuntu ${{ matrix.command }} ubuntu
${{ matrix.command }} debian ${{ matrix.command }} debian
${{ matrix.command }} debian --ci ${{ matrix.command }} debian --ci
${{ matrix.command }} kali # ${{ matrix.command }} kali
${{ matrix.command }} alpine # ${{ matrix.command }} alpine
${{ matrix.command }} opensuse # ${{ matrix.command }} opensuse
${{ matrix.command }} arch # ${{ matrix.command }} arch
${{ matrix.command }} gentoo # ${{ matrix.command }} gentoo
${{ matrix.command }} netboot.xyz ${{ matrix.command }} netboot.xyz
${{ matrix.command }} dd --img=https://download.opensuse.org/tumbleweed/appliances/openSUSE-MicroOS.x86_64-SelfInstall.raw.xz ${{ matrix.command }} dd --img=https://download.opensuse.org/tumbleweed/appliances/openSUSE-MicroOS.x86_64-SelfInstall.raw.xz

View File

@ -4,7 +4,8 @@
[![Codacy](https://img.shields.io/codacy/grade/dc679a17751448628fe6d8ac35e26eed?logo=Codacy&label=Codacy&style=flat-square)](https://app.codacy.com/gh/bin456789/reinstall/dashboard) [![Codacy](https://img.shields.io/codacy/grade/dc679a17751448628fe6d8ac35e26eed?logo=Codacy&label=Codacy&style=flat-square)](https://app.codacy.com/gh/bin456789/reinstall/dashboard)
[![CodeFactor](https://img.shields.io/codefactor/grade/github/bin456789/reinstall?logo=CodeFactor&logoColor=white&label=CodeFactor&style=flat-square)](https://www.codefactor.io/repository/github/bin456789/reinstall) [![CodeFactor](https://img.shields.io/codefactor/grade/github/bin456789/reinstall?logo=CodeFactor&logoColor=white&label=CodeFactor&style=flat-square)](https://www.codefactor.io/repository/github/bin456789/reinstall)
[![Lines of Code](https://tokei.rs/b1/github/bin456789/reinstall?category=code&label=Lines%20of%20Code&style=flat-square)](https://github.com/XAMPPRocky/tokei_rs) [![Lines of Code](https://aschey.tech/tokei/github/bin456789/reinstall?category=code&label=Lines%20of%20Code&style=flat-square)](https://github.com/aschey/vercel-tokei)
<!-- [![Lines of Code](https://tokei.rs/b1/github/bin456789/reinstall?category=code&label=Lines%20of%20Code&style=flat-square)](https://github.com/XAMPPRocky/tokei_rs) -->
One-Click system reinstallation script for VPS [中文](README.md) One-Click system reinstallation script for VPS [中文](README.md)
@ -34,7 +35,7 @@ If this helped you, you can buy me a milk tea.
- [Download](#download-current-system-is--linux) - [Download](#download-current-system-is--linux)
- [Feature 1. One-click reinstallation to Linux](#feature-1-install--linux) - [Feature 1. One-click reinstallation to Linux](#feature-1-install--linux)
- [Feature 2. One-click DD Raw image to hard disk](#feature-2-dd-raw-image-to-hard-disk) - [Feature 2. One-click DD Raw image to hard disk](#feature-2-dd-raw-image-to-hard-disk)
- [Feature 3. One-click reboot to Alpine Live OS in-memory system](#feature-3-reboot-to--alpine-live-os-ram-os) - [Feature 3. One-click reboot to Alpine Live OS](#feature-3-reboot-to--alpine-live-os)
- [Feature 4. One-click reboot to netboot.xyz](#feature-4-reboot-to--netbootxyz) - [Feature 4. One-click reboot to netboot.xyz](#feature-4-reboot-to--netbootxyz)
- [Feature 5. One-click reinstallation to Windows](#feature-5-install--windows-iso) - [Feature 5. One-click reinstallation to Windows](#feature-5-install--windows-iso)
@ -46,22 +47,22 @@ The system requirements for the target system are as follows:
| System | Version | Memory | Disk | | System | Version | Memory | Disk |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | --------- | ---------------- | | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | --------- | ---------------- |
| <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine | 3.19, 3.20, 3.21, 3.22 | 256 MB | 1 GB | | <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine | 3.20, 3.21, 3.22, 3.23 | 256 MB | 1 GB |
| <img width="16" height="16" src="https://www.debian.org/favicon.ico" /> Debian | 9, 10, 11, 12, 13 | 256 MB | 1 ~ 1.5 GB ^ | | <img width="16" height="16" src="https://www.debian.org/favicon.ico" /> Debian | 9, 10, 11, 12, 13 | 256 MB | 1 ~ 1.5 GB ^ |
| <img width="16" height="16" src="https://github.com/bin456789/reinstall/assets/7548515/f74b3d5b-085f-4df3-bcc9-8a9bd80bb16d" /> Kali | Rolling | 256 MB | 1 ~ 1.5 GB ^ | | <img width="16" height="16" src="https://github.com/bin456789/reinstall/assets/7548515/f74b3d5b-085f-4df3-bcc9-8a9bd80bb16d" /> Kali | Rolling | 256 MB | 1 ~ 1.5 GB ^ |
| <img width="16" height="16" src="https://documentation.ubuntu.com/server/_static/favicon.png" /> Ubuntu | 16.04 LTS - 24.04 LTS, 25.04 | 512 MB \* | 2 GB | | <img width="16" height="16" src="https://documentation.ubuntu.com/server/_static/favicon.png" /> Ubuntu | 16.04 LTS - 24.04 LTS, 25.10 | 512 MB \* | 2 GB |
| <img width="16" height="16" src="https://img.alicdn.com/imgextra/i1/O1CN01oJnJZg1yK4RzI4Rx2_!!6000000006559-2-tps-118-118.png" /> Anolis | 7, 8, 23 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://img.alicdn.com/imgextra/i1/O1CN01oJnJZg1yK4RzI4Rx2_!!6000000006559-2-tps-118-118.png" /> Anolis | 7, 8, 23 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://www.redhat.com/favicon.ico" /> RHEL &nbsp;<img width="16" height="16" src="https://almalinux.org/fav/favicon.ico" /> AlmaLinux &nbsp;<img width="16" height="16" src="https://rockylinux.org/favicon.png" /> Rocky &nbsp;<img width="16" height="16" src="https://www.oracle.com/asset/web/favicons/favicon-32.png" /> Oracle | 8, 9, 10 (if released) | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://www.redhat.com/favicon.ico" /> RHEL &nbsp;<img width="16" height="16" src="https://almalinux.org/fav/favicon.ico" /> AlmaLinux &nbsp;<img width="16" height="16" src="https://rockylinux.org/favicon.png" /> Rocky &nbsp;<img width="16" height="16" src="https://www.oracle.com/asset/web/favicons/favicon-32.png" /> Oracle | 8, 9, 10 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://opencloudos.org/qq.ico" /> OpenCloudOS | 8, 9, Stream 23 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://opencloudos.org/qq.ico" /> OpenCloudOS | 8, 9, Stream 23 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://www.centos.org/assets/icons/favicon.svg" /> CentOS Stream | 9, 10 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://www.centos.org/assets/icons/favicon.svg" /> CentOS Stream | 9, 10 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://fedoraproject.org/favicon.ico" /> Fedora | 41, 42 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://fedoraproject.org/favicon.ico" /> Fedora | 42, 43 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://www.openeuler.org/favicon.ico" /> openEuler | 20.03 LTS - 24.03 LTS, 25.03 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://www.openeuler.org/favicon.ico" /> openEuler | 20.03 LTS - 24.03 LTS, 25.09 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://static.opensuse.org/favicon.ico" /> openSUSE | Leap 15.6, Tumbleweed (Rolling) | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://static.opensuse.org/favicon.ico" /> openSUSE | Leap 15.6, 16.0, Tumbleweed (Rolling) | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://nixos.org/favicon.svg" /> NixOS | 25.05 | 512 MB | 5 GB | | <img width="16" height="16" src="https://nixos.org/favicon.svg" /> NixOS | 25.11 | 512 MB | 5 GB |
| <img width="16" height="16" src="https://archlinux.org/static/favicon.png" /> Arch | Rolling | 512 MB | 5 GB | | <img width="16" height="16" src="https://archlinux.org/static/favicon.png" /> Arch | Rolling | 512 MB | 5 GB |
| <img width="16" height="16" src="https://www.gentoo.org/assets/img/logo/gentoo-g.png" /> Gentoo | Rolling | 512 MB | 5 GB | | <img width="16" height="16" src="https://www.gentoo.org/assets/img/logo/gentoo-g.png" /> Gentoo | Rolling | 512 MB | 5 GB |
| <img width="16" height="16" src="https://aosc.io/assets/distros/aosc-os.svg" /> AOSC OS | Rolling | 512 MB | 5 GB | | <img width="16" height="16" src="https://aosc.io/distros/aosc-os.svg" /> AOSC OS | Rolling | 512 MB | 5 GB |
| <img width="16" height="16" src="https://www.fnnas.com/favicon.ico" /> fnOS | Beta | 512 MB | 8 GB | | <img width="16" height="16" src="https://www.fnnas.com/favicon.ico" /> fnOS | 1 | 512 MB | 8 GB |
| <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (DD) | Any | 512 MB | Depends on image | | <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (DD) | Any | 512 MB | Depends on image |
| <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (ISO) | Vista, 7, 8.x (Server 2008 - 2012 R2) | 512 MB | 25 GB | | <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (ISO) | Vista, 7, 8.x (Server 2008 - 2012 R2) | 512 MB | 25 GB |
| <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (ISO) | 10, 11 (Server 2016 - 2025) | 1 GB | 25 GB | | <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (ISO) | 10, 11 (Server 2016 - 2025) | 1 GB | 25 GB |
@ -145,32 +146,32 @@ certutil -urlcache -f -split https://cnb.cool/bin456789/reinstall/-/git/raw/main
> >
> Data is priceless — please think twice before proceeding! > Data is priceless — please think twice before proceeding!
- The username is `root` with a default password of `123@@@`. - Username `root`. The script prompts for a password. If left blank, a random one is generated.
- When installing the latest version, the version number does not need to be specified. - When installing the latest version, the version number does not need to be specified.
- Maximizes disk space usage: no boot partition (except for Fedora) and no swap partition. - Maximizes disk space usage: no boot partition (except for Fedora) and no swap partition.
- Automatically selects different optimized kernels based on machine type, such as `Cloud` or `HWE` kernels. - Automatically selects different optimized kernels based on machine type, such as `Cloud` or `HWE` kernels.
- When installing Red Hat, you must provide the `qcow2` image link obtained from <https://access.redhat.com/downloads/content/rhel>. You can also install other RHEL-based OS, such as `Alibaba Cloud Linux` and `TencentOS Server`. - When installing Red Hat, you must provide the `qcow2` image link obtained from <https://access.redhat.com/downloads/content/rhel>. You can also install `qcow2` of other RHEL-based OS, such as `Alibaba Cloud Linux` and `TencentOS Server`.
- After reinstallation, if you need to change the SSH port or switch to key-based login, make sure to also modify the files inside `/etc/ssh/sshd_config.d/`. - After reinstallation, if you need to change the SSH port or switch to key-based login, make sure to also modify the files inside `/etc/ssh/sshd_config.d/`.
```bash ```bash
bash reinstall.sh anolis 7|8|23 bash reinstall.sh anolis 7|8|23
rocky 8|9|10 rocky 8|9|10
oracle 8|9 oracle 8|9|10
almalinux 8|9|10 almalinux 8|9|10
opencloudos 8|9|23 opencloudos 8|9|23
centos 9|10 centos 9|10
fedora 41|42 fnos 1
nixos 25.05 nixos 25.11
fedora 42|43
debian 9|10|11|12|13 debian 9|10|11|12|13
opensuse 15.6|tumbleweed alpine 3.20|3.21|3.22|3.23
alpine 3.19|3.20|3.21|3.22 opensuse 15.6|16.0|tumbleweed
openeuler 20.03|22.03|24.03|25.03 openeuler 20.03|22.03|24.03|25.09
ubuntu 16.04|18.04|20.04|22.04|24.04|25.04 [--minimal] ubuntu 16.04|18.04|20.04|22.04|24.04|25.10 [--minimal]
kali kali
arch arch
gentoo gentoo
aosc aosc
fnos
redhat --img="http://access.cdn.redhat.com/xxx.qcow2" redhat --img="http://access.cdn.redhat.com/xxx.qcow2"
``` ```
@ -180,14 +181,17 @@ bash reinstall.sh anolis 7|8|23
- `--ssh-key KEY` Set up SSH login public key, [formatted as follows](#--ssh-key). When using public key, password is empty. - `--ssh-key KEY` Set up SSH login public key, [formatted as follows](#--ssh-key). When using public key, password is empty.
- `--ssh-port PORT` Change the SSH port (for log observation during installation and for the new system) - `--ssh-port PORT` Change the SSH port (for log observation during installation and for the new system)
- `--web-port PORT` Change the Web port (for log observation during installation only) - `--web-port PORT` Change the Web port (for log observation during installation only)
- `--frpc-toml /path/to/frpc.toml` Add frpc for intranet tunneling - `--frpc-toml PATH` Add frpc for intranet tunneling. Parameter can be local filepath or HTTP URL
- `--hold 2` Prevent reboot after installation completes, allowing SSH login to modify system content; the system is mounted at `/os` (this feature is not supported on Debian/Kali). - `--hold 1` Reboot only into install environment, without running installer, only for SSH connect to test network connection.
- `--hold 2` Prevent reboot after installation completes, allowing SSH login to modify system content; the system is mounted at `/target` for Debian/Kali and `/os` for other distros.
> [!TIP] > [!TIP]
> When installing Debian/Kali, x86 architectures can monitor the installation progress through VNC from server provider, while ARM architectures can use the serial console.
> >
> When installing other systems, can monitor the progress through various methods (SSH, HTTP 80 port, VNC from server provider, serial console). > Can monitor the progress through various methods (SSH, HTTP 80 port, VNC from server provider, serial console).
> <br />Even if errors occur during the installation process, you can still install to Alpine via SSH by running `/trans.sh alpine` >
> Even if errors occur during the installation process, SSH is available for manual recovery.
>
> If the target system is not Debian/Kali, run `/trans.sh alpine` can automatically recover to Alpine Linux.
<details> <details>
@ -229,7 +233,7 @@ bash reinstall.sh ubuntu --installer
> >
> Data is priceless — please think twice before proceeding! > Data is priceless — please think twice before proceeding!
- Supports `raw` and `vhd` image formats (either uncompressed or compressed as `.gz`, `.xz`, `.zst`, `.tar`, `.tar.gz`, `.tar.xz`, `.tar.zst`). - Supports `raw` and fixed-size `vhd` image formats. Either uncompressed or compressed as `.gz`, `.xz`, `.zst`, `.tar`, `.tar.gz`, `.tar.xz`, `.tar.zst`.
- When deploy a Windows image, the system disk will be automatically expanded, and machines with a static IP will have their IP configured, and may take a few minutes after the first boot for the configuration to take effect. - When deploy a Windows image, the system disk will be automatically expanded, and machines with a static IP will have their IP configured, and may take a few minutes after the first boot for the configuration to take effect.
- When deploy a Linux image, will **NOT** modify any contents of the image. - When deploy a Linux image, will **NOT** modify any contents of the image.
@ -243,26 +247,31 @@ bash reinstall.sh dd --img "https://example.com/xxx.xz"
- `--rdp-port PORT` Change RDP port (DD Windows only) - `--rdp-port PORT` Change RDP port (DD Windows only)
- `--ssh-port PORT` Change SSH port (for log observation during installation) - `--ssh-port PORT` Change SSH port (for log observation during installation)
- `--web-port PORT` Change Web port (for log observation during installation) - `--web-port PORT` Change Web port (for log observation during installation)
- `--frpc-toml /path/to/frpc.toml` Add frpc for intranet tunneling (DD Windows only) - `--frpc-toml PATH` Add frpc for intranet tunneling (DD Windows only). Parameter can be local filepath or HTTP URL
- `--hold 2` Prevent reboot after the DD process finishes, allowing SSH login to modify system content. The Windows system will be mounted at `/os`, but Linux systems will **NOT** be automatically mounted. - `--hold 1` Reboot only into install environment, without running installer, only for SSH connect to test network connection.
- `--hold 2` Prevent reboot after the DD process finishes. For SSH login to modify system content. The Windows system will be mounted at `/os`, but Linux systems will **NOT** be automatically mounted.
> [!TIP] > [!TIP]
>
> Can monitor the progress through various methods (SSH, HTTP 80 port, VNC from server provider, serial console). > Can monitor the progress through various methods (SSH, HTTP 80 port, VNC from server provider, serial console).
> <br />Even if errors occur during the installation process, you can still install to Alpine via SSH by running `/trans.sh alpine` >
> Even if errors occur during the installation process, SSH is available for manual recovery.
>
> Or Run `/trans.sh alpine` to automatically recover to Alpine Linux.
### Feature 3: Reboot to <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine Live OS (RAM OS) ### Feature 3: Reboot to <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine Live OS
- You can use SSH to backup/restore disk, manually perform DD operations, partition modifications, manual Alpine installation, and other operations. - You can use SSH to backup/restore disk, manually perform DD operations, partition modifications, manual Alpine installation, and other operations.
- Username `root`, Default password `123@@@` - Username `root`. The script prompts for a password. If left blank, a random one is generated.
> [!TIP] > [!TIP]
> >
> Although the script being run is `reinstall`, this feature **does not** delete any data or perform an automatic reinstallation; manual user operation is required. > Although the script being run is `reinstall`, this feature **does not** delete any data or perform an automatic reinstallation; manual user operation is required.
>
> If the user does not damage the original system during manual operation, rebooting will return to the original system. > If the user does not damage the original system during manual operation, rebooting will return to the original system.
```bash ```bash
bash reinstall.sh alpine --hold=1 bash reinstall.sh alpine --hold 1
``` ```
#### Optional Parameters #### Optional Parameters
@ -270,7 +279,7 @@ bash reinstall.sh alpine --hold=1
- `--password PASSWORD` Set password - `--password PASSWORD` Set password
- `--ssh-port PORT` Change SSH port - `--ssh-port PORT` Change SSH port
- `--ssh-key KEY` Set up SSH login public key, [formatted as follows](#--ssh-key). When using public key, password is empty. - `--ssh-key KEY` Set up SSH login public key, [formatted as follows](#--ssh-key). When using public key, password is empty.
- `--frpc-toml /path/to/frpc.toml` Add frpc for intranet tunneling - `--frpc-toml PATH` Add frpc for intranet tunneling. Parameter can be local filepath or HTTP URL
### Feature 4: Reboot to <img width="16" height="16" src="https://netboot.xyz/img/favicon.ico" /> netboot.xyz ### Feature 4: Reboot to <img width="16" height="16" src="https://netboot.xyz/img/favicon.ico" /> netboot.xyz
@ -279,7 +288,7 @@ bash reinstall.sh alpine --hold=1
> [!TIP] > [!TIP]
> >
> Although the script being run is `reinstall`, this feature **does not** delete any data or perform an automatic reinstallation; manual user operation is required. > Although the script being run is `reinstall`, this feature **does not** delete any data or perform an automatic reinstallation; manual user operation is required.
>
> If the user does not damage the original system during manual operation, rebooting will return to the original system. > If the user does not damage the original system during manual operation, rebooting will return to the original system.
```bash ```bash
@ -298,10 +307,11 @@ bash reinstall.sh netboot.xyz
> >
> Data is priceless — please think twice before proceeding! > Data is priceless — please think twice before proceeding!
- Username `administrator`, Default password `123@@@` - Username `administrator`. The script prompts for a password. If left blank, a random one is generated.
- If remote login fails, try using the username `.\administrator`. - If remote login fails, try using the username `.\administrator`.
- The machine with a static IP will automatically configure the IP. It may take a few minutes to take effect on the first boot. - The machine with a static IP will automatically configure the IP. It may take a few minutes to take effect on the first boot.
- Supports all languages. - Supports ISO images in any language.
- Supports bypassing Windows 11 hardware requirements.
#### Supported Systems #### Supported Systems
@ -401,7 +411,6 @@ bash reinstall.sh windows \
- <https://www.microsoft.com/software-download/windows11> - <https://www.microsoft.com/software-download/windows11>
- <https://www.microsoft.com/software-download/windows11arm64> - <https://www.microsoft.com/software-download/windows11arm64>
- Evaluation - Evaluation
- <https://www.microsoft.com/evalcenter/download-windows-10-enterprise>
- <https://www.microsoft.com/evalcenter/download-windows-11-enterprise> - <https://www.microsoft.com/evalcenter/download-windows-11-enterprise>
- <https://www.microsoft.com/evalcenter/download-windows-11-iot-enterprise-ltsc-eval> - <https://www.microsoft.com/evalcenter/download-windows-11-iot-enterprise-ltsc-eval>
- <https://www.microsoft.com/evalcenter/download-windows-server-2012-r2> - <https://www.microsoft.com/evalcenter/download-windows-server-2012-r2>
@ -425,8 +434,9 @@ bash reinstall.sh windows \
- `--add-driver INF_OR_DIR` Add additional driver, specifying .inf path, or the folder contains .inf file. - `--add-driver INF_OR_DIR` Add additional driver, specifying .inf path, or the folder contains .inf file.
- The driver must be downloaded to current system first. - The driver must be downloaded to current system first.
- This parameter can be set multiple times to add different driver. - This parameter can be set multiple times to add different driver.
- `--frpc-toml /path/to/frpc.toml` Add frpc for intranet tunneling - `--frpc-toml PATH` Add frpc for intranet tunneling. Parameter can be local filepath or HTTP URL
- `--hold 2` Allow SSH connections for modifying the disk content before rebooting into the official Windows installation program, with the disk mounted at `/os`. - `--hold 1` Reboot only into install environment, without running installer, only for SSH connect to test network connection.
- `--hold 2` Allow SSH connections for modifying `boot.wim`, `install.wim` or other contents before rebooting into the official Windows installation program, with the disk mounted at `/os`.
#### The following drivers will automatic download and install as needed, without the need for manual addition #### The following drivers will automatic download and install as needed, without the need for manual addition
@ -488,15 +498,29 @@ Open File menu > Open Image File, select the iso to be installed to get the imag
> Vista (Server 2008) and 32-bit systems may lack drivers. > Vista (Server 2008) and 32-bit systems may lack drivers.
> [!WARNING] > [!WARNING]
> For EFI machines without CSM enabled, Windows 7 (Server 2008 R2) cannot be installed.
> >
> Hyper-V (Azure) requires selecting the appropriate VM generation: <https://learn.microsoft.com/windows-server/virtualization/hyper-v/plan/should-i-create-a-generation-1-or-2-virtual-machine-in-hyper-v> > For Windows 7 (Server 2008 R2) installation:
>
> 1. EFI-boot machines must enable CSM.
>
> 2. On Hyper-V (Azure), select Generation 1 VM. <https://learn.microsoft.com/windows-server/virtualization/hyper-v/plan/should-i-create-a-generation-1-or-2-virtual-machine-in-hyper-v>
> [!WARNING] > [!WARNING]
>
> In the Chinese version of Windows 10 LTSC 2021 ISO `zh-cn_windows_10_enterprise_ltsc_2021_x64_dvd_033b7312.iso`, the `wsappx` process may indefinitely consume CPU resources. > In the Chinese version of Windows 10 LTSC 2021 ISO `zh-cn_windows_10_enterprise_ltsc_2021_x64_dvd_033b7312.iso`, the `wsappx` process may indefinitely consume CPU resources.
> >
> The solution is to update the system patches or manually install the `VCLibs` library <https://www.google.com/search?q=ltsc+wsappx>. > The solution is to update the system patches or manually install the `VCLibs` library <https://www.google.com/search?q=ltsc+wsappx>.
> [!WARNING]
>
> When installing Windows ISOs released in `May 2022` or later on GCP, the system may repeatedly reboot during the Windows installation (PE) stage. You can resolve this issue using one of the following two methods:
>
> 1. Add the `--force-boot-mode bios` parameter. The script will install Windows in `BIOS boot + MBR partition table` mode.
>
> (Optional) After installation, you can convert it to `EFI boot + GPT partition table` using the command `MBR2GPT /convert /allowFullOS`.
>
> 2. Create a custom RAW image and install it via DD.
#### Considerations for Installing Windows on ARM #### Considerations for Installing Windows on ARM
Most ARM machines support installing latest Windows 11. Most ARM machines support installing latest Windows 11.
@ -539,6 +563,21 @@ Log in to the server using Remote Desktop, open Device Manager, locate the graph
- `--ssh-key /path/to/public_key` - `--ssh-key /path/to/public_key`
- `--ssh-key C:\path\to\public_key` - `--ssh-key C:\path\to\public_key`
## How to Use an Old Version
According to the Law of Bug Conservation, fixing old bugs often introduces new ones.
If a new bug occurs, try using an older version to see if it works.
Go to <https://github.com/bin456789/reinstall/commits/main> and find the old versions `commit_id` on the right side.
```bash
commit_id=xxxxxxx
curl -O https://raw.githubusercontent.com/bin456789/reinstall/$commit_id/reinstall.sh || wget -O ${_##*/} $_
sed -i "/^confhome.*main$/s/main/$commit_id/" reinstall.sh
bash reinstall.sh ...
```
## How to Modify the Script for Your Own ## How to Modify the Script for Your Own
1. Fork this repository. 1. Fork this repository.

117
README.md
View File

@ -4,7 +4,8 @@
[![Codacy](https://img.shields.io/codacy/grade/dc679a17751448628fe6d8ac35e26eed?logo=Codacy&label=Codacy&style=flat-square)](https://app.codacy.com/gh/bin456789/reinstall/dashboard) [![Codacy](https://img.shields.io/codacy/grade/dc679a17751448628fe6d8ac35e26eed?logo=Codacy&label=Codacy&style=flat-square)](https://app.codacy.com/gh/bin456789/reinstall/dashboard)
[![CodeFactor](https://img.shields.io/codefactor/grade/github/bin456789/reinstall?logo=CodeFactor&logoColor=white&label=CodeFactor&style=flat-square)](https://www.codefactor.io/repository/github/bin456789/reinstall) [![CodeFactor](https://img.shields.io/codefactor/grade/github/bin456789/reinstall?logo=CodeFactor&logoColor=white&label=CodeFactor&style=flat-square)](https://www.codefactor.io/repository/github/bin456789/reinstall)
[![Lines of Code](https://tokei.rs/b1/github/bin456789/reinstall?category=code&label=Lines%20of%20Code&style=flat-square)](https://github.com/XAMPPRocky/tokei_rs) [![Lines of Code](https://aschey.tech/tokei/github/bin456789/reinstall?category=code&label=Lines%20of%20Code&style=flat-square)](https://github.com/aschey/vercel-tokei)
<!-- [![Lines of Code](https://tokei.rs/b1/github/bin456789/reinstall?category=code&label=Lines%20of%20Code&style=flat-square)](https://github.com/XAMPPRocky/tokei_rs) -->
一键 VPS 系统重装脚本 [English](README.en.md) 一键 VPS 系统重装脚本 [English](README.en.md)
@ -46,22 +47,22 @@
| 系统 | 版本 | 内存 | 硬盘 | | 系统 | 版本 | 内存 | 硬盘 |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | --------- | ------------ | | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | --------- | ------------ |
| <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine | 3.19, 3.20, 3.21, 3.22 | 256 MB | 1 GB | | <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine | 3.20, 3.21, 3.22, 3.23 | 256 MB | 1 GB |
| <img width="16" height="16" src="https://www.debian.org/favicon.ico" /> Debian | 9, 10, 11, 12, 13 | 256 MB | 1 ~ 1.5 GB ^ | | <img width="16" height="16" src="https://www.debian.org/favicon.ico" /> Debian | 9, 10, 11, 12, 13 | 256 MB | 1 ~ 1.5 GB ^ |
| <img width="16" height="16" src="https://github.com/bin456789/reinstall/assets/7548515/f74b3d5b-085f-4df3-bcc9-8a9bd80bb16d" /> Kali | 滚动 | 256 MB | 1 ~ 1.5 GB ^ | | <img width="16" height="16" src="https://github.com/bin456789/reinstall/assets/7548515/f74b3d5b-085f-4df3-bcc9-8a9bd80bb16d" /> Kali | 滚动 | 256 MB | 1 ~ 1.5 GB ^ |
| <img width="16" height="16" src="https://documentation.ubuntu.com/server/_static/favicon.png" /> Ubuntu | 16.04 LTS - 24.04 LTS, 25.04 | 512 MB \* | 2 GB | | <img width="16" height="16" src="https://documentation.ubuntu.com/server/_static/favicon.png" /> Ubuntu | 16.04 LTS - 24.04 LTS, 25.10 | 512 MB \* | 2 GB |
| <img width="16" height="16" src="https://img.alicdn.com/imgextra/i1/O1CN01oJnJZg1yK4RzI4Rx2_!!6000000006559-2-tps-118-118.png" /> Anolis | 7, 8, 23 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://img.alicdn.com/imgextra/i1/O1CN01oJnJZg1yK4RzI4Rx2_!!6000000006559-2-tps-118-118.png" /> Anolis | 7, 8, 23 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://www.redhat.com/favicon.ico" /> RHEL &nbsp;<img width="16" height="16" src="https://almalinux.org/fav/favicon.ico" /> AlmaLinux &nbsp;<img width="16" height="16" src="https://rockylinux.org/favicon.png" /> Rocky &nbsp;<img width="16" height="16" src="https://www.oracle.com/asset/web/favicons/favicon-32.png" /> Oracle | 8, 9, 10 (如果有) | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://www.redhat.com/favicon.ico" /> RHEL &nbsp;<img width="16" height="16" src="https://almalinux.org/fav/favicon.ico" /> AlmaLinux &nbsp;<img width="16" height="16" src="https://rockylinux.org/favicon.png" /> Rocky &nbsp;<img width="16" height="16" src="https://www.oracle.com/asset/web/favicons/favicon-32.png" /> Oracle | 8, 9, 10 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://opencloudos.org/qq.ico" /> OpenCloudOS | 8, 9, Stream 23 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://opencloudos.org/qq.ico" /> OpenCloudOS | 8, 9, Stream 23 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://www.centos.org/assets/icons/favicon.svg" /> CentOS Stream | 9, 10 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://www.centos.org/assets/icons/favicon.svg" /> CentOS Stream | 9, 10 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://fedoraproject.org/favicon.ico" /> Fedora | 41, 42 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://fedoraproject.org/favicon.ico" /> Fedora | 42, 43 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://www.openeuler.org/favicon.ico" /> openEuler | 20.03 LTS - 24.03 LTS, 25.03 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://www.openeuler.org/favicon.ico" /> openEuler | 20.03 LTS - 24.03 LTS, 25.09 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://static.opensuse.org/favicon.ico" /> openSUSE | Leap 15.6, Tumbleweed (滚动) | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://static.opensuse.org/favicon.ico" /> openSUSE | Leap 15.6, 16.0, Tumbleweed (滚动) | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://nixos.org/favicon.svg" /> NixOS | 25.05 | 512 MB | 5 GB | | <img width="16" height="16" src="https://nixos.org/favicon.svg" /> NixOS | 25.11 | 512 MB | 5 GB |
| <img width="16" height="16" src="https://archlinux.org/static/favicon.png" /> Arch | 滚动 | 512 MB | 5 GB | | <img width="16" height="16" src="https://archlinux.org/static/favicon.png" /> Arch | 滚动 | 512 MB | 5 GB |
| <img width="16" height="16" src="https://www.gentoo.org/assets/img/logo/gentoo-g.png" /> Gentoo | 滚动 | 512 MB | 5 GB | | <img width="16" height="16" src="https://www.gentoo.org/assets/img/logo/gentoo-g.png" /> Gentoo | 滚动 | 512 MB | 5 GB |
| <img width="16" height="16" src="https://aosc.io/assets/distros/aosc-os.svg" /> 安同 OS | 滚动 | 512 MB | 5 GB | | <img width="16" height="16" src="https://aosc.io/distros/aosc-os.svg" /> 安同 OS | 滚动 | 512 MB | 5 GB |
| <img width="16" height="16" src="https://www.fnnas.com/favicon.ico" /> 飞牛 fnOS | 公测 | 512 MB | 8 GB | | <img width="16" height="16" src="https://www.fnnas.com/favicon.ico" /> 飞牛 fnOS | 1 | 512 MB | 8 GB |
| <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (DD) | 任何 | 512 MB | 取决于镜像 | | <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (DD) | 任何 | 512 MB | 取决于镜像 |
| <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (ISO) | Vista, 7, 8.x (Server 2008 - 2012 R2) | 512 MB | 25 GB | | <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (ISO) | Vista, 7, 8.x (Server 2008 - 2012 R2) | 512 MB | 25 GB |
| <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (ISO) | 10, 11 (Server 2016 - 2025) | 1 GB | 25 GB | | <img width="16" height="16" src="https://blogs.windows.com/wp-content/uploads/prod/2022/09/cropped-Windows11IconTransparent512-32x32.png" /> Windows (ISO) | 10, 11 (Server 2016 - 2025) | 1 GB | 25 GB |
@ -145,32 +146,32 @@ certutil -urlcache -f -split https://cnb.cool/bin456789/reinstall/-/git/raw/main
> >
> 数据无价,请三思而后行! > 数据无价,请三思而后行!
- 用户名 `root` 默认密码 `123@@@` - 用户名 `root`,脚本会提示输入密码,不输入则使用随机密码
- 安装最新版可不输入版本号 - 安装最新版可不输入版本号
- 最大化利用磁盘空间:不含 boot 分区Fedora 例外),不含 swap 分区 - 最大化利用磁盘空间:不含 boot 分区Fedora 例外),不含 swap 分区
- 自动根据机器类型选择不同的优化内核,例如 `Cloud``HWE` 内核 - 自动根据机器类型选择不同的优化内核,例如 `Cloud``HWE` 内核
- 安装 Red Hat 时需填写 <https://access.redhat.com/downloads/content/rhel> 得到的 `qcow2` 镜像链接,也可以安装其它类 RHEL 系统,例如 `Alibaba Cloud Linux``TencentOS Server` - 安装 Red Hat 时需填写 <https://access.redhat.com/downloads/content/rhel> 得到的 `qcow2` 镜像链接,也可以安装其它类 RHEL 系统`qcow2`,例如 `Alibaba Cloud Linux``TencentOS Server`
- 重装后如需修改 SSH 端口或者改成密钥登录,注意还要修改 `/etc/ssh/sshd_config.d/` 里面的文件 - 重装后如需修改 SSH 端口或者改成密钥登录,注意还要修改 `/etc/ssh/sshd_config.d/` 里面的文件
```bash ```bash
bash reinstall.sh anolis 7|8|23 bash reinstall.sh anolis 7|8|23
rocky 8|9|10 rocky 8|9|10
oracle 8|9 oracle 8|9|10
almalinux 8|9|10 almalinux 8|9|10
opencloudos 8|9|23 opencloudos 8|9|23
centos 9|10 centos 9|10
fedora 41|42 fnos 1
nixos 25.05 nixos 25.11
fedora 42|43
debian 9|10|11|12|13 debian 9|10|11|12|13
opensuse 15.6|tumbleweed alpine 3.20|3.21|3.22|3.23
alpine 3.19|3.20|3.21|3.22 opensuse 15.6|16.0|tumbleweed
openeuler 20.03|22.03|24.03|25.03 openeuler 20.03|22.03|24.03|25.09
ubuntu 16.04|18.04|20.04|22.04|24.04|25.04 [--minimal] ubuntu 16.04|18.04|20.04|22.04|24.04|25.10 [--minimal]
kali kali
arch arch
gentoo gentoo
aosc aosc
fnos
redhat --img="http://access.cdn.redhat.com/xxx.qcow2" redhat --img="http://access.cdn.redhat.com/xxx.qcow2"
``` ```
@ -180,14 +181,17 @@ bash reinstall.sh anolis 7|8|23
- `--ssh-key KEY` 设置 SSH 登录公钥,[格式如下](#--ssh-key)。当使用公钥时,密码为空 - `--ssh-key KEY` 设置 SSH 登录公钥,[格式如下](#--ssh-key)。当使用公钥时,密码为空
- `--ssh-port PORT` 修改 SSH 端口(安装期间观察日志用,也作用于新系统) - `--ssh-port PORT` 修改 SSH 端口(安装期间观察日志用,也作用于新系统)
- `--web-port PORT` 修改 Web 端口(安装期间观察日志用) - `--web-port PORT` 修改 Web 端口(安装期间观察日志用)
- `--frpc-toml /path/to/frpc.toml` 添加 frpc 内网穿透 - `--frpc-toml PATH` 添加 frpc 内网穿透,参数填本地路径或 HTTP 链接
- `--hold 2` 安装结束后不重启,此时可以 SSH 登录修改系统内容,系统挂载在 `/os` (此功能不支持 Debian/Kali) - `--hold 1` 仅重启到安装环境,不运行安装,用于 SSH 登录验证网络连通性
- `--hold 2` 安装结束后不重启,用于 SSH 登录修改系统内容Debian/Kali 会挂载在 `/target`,其它系统会挂载在 `/os`
> [!TIP] > [!TIP]
> 安装 Debian/Kali 时x86 可通过商家后台 VNC 查看安装进度ARM 可通过串行控制台查看安装进度。
> >
> 安装其它系统时,可通过多种方式SSH、HTTP 80 端口、商家后台 VNC、串行控制台查看安装进度。 > 可通过多种方式SSH、HTTP 80 端口、商家后台 VNC、串行控制台查看安装进度。
> <br />即使安装过程出错,也能通过 SSH 运行 `/trans.sh alpine` 安装到 Alpine。 >
> 即使安装过程出错,也能连接 SSH 手动救砖。
>
> 目标系统非 Debian/Kali 时,可以运行 `/trans.sh alpine` 自动救砖成 Alpine 系统。
<details> <details>
@ -229,7 +233,7 @@ bash reinstall.sh ubuntu --installer
> >
> 数据无价,请三思而后行! > 数据无价,请三思而后行!
- 支持 `raw` `vhd` 格式的镜像未压缩或者压缩成 `.gz` `.xz` `.zst` `.tar` `.tar.gz` `.tar.xz` `.tar.zst` - 支持 `raw` 和固定大小的 `vhd` 镜像未压缩或者压缩成 `.gz` `.xz` `.zst` `.tar` `.tar.gz` `.tar.xz` `.tar.zst`
- DD Windows 镜像时,会自动扩展系统盘,静态 IP 的机器会配置好 IP可能首次开机几分钟后才生效 - DD Windows 镜像时,会自动扩展系统盘,静态 IP 的机器会配置好 IP可能首次开机几分钟后才生效
- DD Linux 镜像时,**不会**修改镜像的任何内容 - DD Linux 镜像时,**不会**修改镜像的任何内容
@ -243,17 +247,22 @@ bash reinstall.sh dd --img "https://example.com/xxx.xz"
- `--rdp-port PORT` 修改 RDP 端口 (仅限 DD Windows) - `--rdp-port PORT` 修改 RDP 端口 (仅限 DD Windows)
- `--ssh-port PORT` 修改 SSH 端口(安装期间观察日志用) - `--ssh-port PORT` 修改 SSH 端口(安装期间观察日志用)
- `--web-port PORT` 修改 Web 端口(安装期间观察日志用) - `--web-port PORT` 修改 Web 端口(安装期间观察日志用)
- `--frpc-toml /path/to/frpc.toml` 添加 frpc 内网穿透(仅限 DD Windows - `--frpc-toml PATH` 添加 frpc 内网穿透(仅限 DD Windows,参数填本地路径或 HTTP 链接
- `--hold 2` DD 结束后不重启,此时可以 SSH 登录修改系统内容Windows 系统会挂载在 `/os`Linux 系统**不会**自动挂载 - `--hold 1` 仅重启到安装环境,不运行安装,用于 SSH 登录验证网络连通性
- `--hold 2` DD 结束后不重启,用于 SSH 登录修改系统内容Windows 系统会挂载在 `/os`Linux 系统**不会**自动挂载
> [!TIP] > [!TIP]
>
> 可通过多种方式SSH、HTTP 80 端口、商家后台 VNC、串行控制台查看安装进度。 > 可通过多种方式SSH、HTTP 80 端口、商家后台 VNC、串行控制台查看安装进度。
> <br />即使安装过程出错,也能通过 SSH 运行 `/trans.sh alpine` 安装到 Alpine。 >
> 即使安装过程出错,也能连接 SSH 手动救砖
>
> 也可以运行 `/trans.sh alpine` 自动救砖成 Alpine 系统。
### 功能 3: 重启到 <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine Live OS内存系统 ### 功能 3: 重启到 <img width="16" height="16" src="https://www.alpinelinux.org/alpine-logo.ico" /> Alpine Live OS内存系统
- 可用 ssh 连接,进行备份/恢复硬盘、手动 DD、修改分区、手动安装 Alpine 等操作 - 可用 ssh 连接,进行备份/恢复硬盘、手动 DD、修改分区、手动安装 Alpine 等操作
- 用户名 `root` 默认密码 `123@@@` - 用户名 `root`,脚本会提示输入密码,不输入则使用随机密码
> [!TIP] > [!TIP]
> >
@ -262,7 +271,7 @@ bash reinstall.sh dd --img "https://example.com/xxx.xz"
> 如果用户手动操作没有破坏原系统,再次重启将回到原系统 > 如果用户手动操作没有破坏原系统,再次重启将回到原系统
```bash ```bash
bash reinstall.sh alpine --hold=1 bash reinstall.sh alpine --hold 1
``` ```
#### 可选参数 #### 可选参数
@ -270,7 +279,7 @@ bash reinstall.sh alpine --hold=1
- `--password PASSWORD` 设置密码 - `--password PASSWORD` 设置密码
- `--ssh-port PORT` 修改 SSH 端口 - `--ssh-port PORT` 修改 SSH 端口
- `--ssh-key KEY` 设置 SSH 登录公钥,[格式如下](#--ssh-key)。当使用公钥时,密码为空 - `--ssh-key KEY` 设置 SSH 登录公钥,[格式如下](#--ssh-key)。当使用公钥时,密码为空
- `--frpc-toml /path/to/frpc.toml` 添加 frpc 内网穿透 - `--frpc-toml PATH` 添加 frpc 内网穿透,参数填本地路径或 HTTP 链接
### 功能 4: 重启到 <img width="16" height="16" src="https://netboot.xyz/img/favicon.ico" /> netboot.xyz ### 功能 4: 重启到 <img width="16" height="16" src="https://netboot.xyz/img/favicon.ico" /> netboot.xyz
@ -298,10 +307,11 @@ bash reinstall.sh netboot.xyz
> >
> 数据无价,请三思而后行! > 数据无价,请三思而后行!
- 用户名 `administrator` 默认密码 `123@@@` - 用户名 `administrator`,脚本会提示输入密码,不输入则使用随机密码
- 如果远程登录失败,可以尝试使用用户名 `.\administrator` - 如果远程登录失败,可以尝试使用用户名 `.\administrator`
- 静态机器会自动配置好 IP可能首次开机几分钟后才生效 - 静态机器会自动配置好 IP可能首次开机几分钟后才生效
- 支持所有语言 - 支持任意语言的 ISO
- 支持绕过 Windows 11 硬件限制
#### 支持的系统 #### 支持的系统
@ -401,7 +411,6 @@ bash reinstall.sh windows \
- <https://www.microsoft.com/software-download/windows11> - <https://www.microsoft.com/software-download/windows11>
- <https://www.microsoft.com/software-download/windows11arm64> - <https://www.microsoft.com/software-download/windows11arm64>
- 评估版 - 评估版
- <https://www.microsoft.com/evalcenter/download-windows-10-enterprise>
- <https://www.microsoft.com/evalcenter/download-windows-11-enterprise> - <https://www.microsoft.com/evalcenter/download-windows-11-enterprise>
- <https://www.microsoft.com/evalcenter/download-windows-11-iot-enterprise-ltsc-eval> - <https://www.microsoft.com/evalcenter/download-windows-11-iot-enterprise-ltsc-eval>
- <https://www.microsoft.com/evalcenter/download-windows-server-2012-r2> - <https://www.microsoft.com/evalcenter/download-windows-server-2012-r2>
@ -425,8 +434,9 @@ bash reinstall.sh windows \
- `--add-driver INF_OR_DIR` 添加额外驱动,填写 .inf 路径,或者 .inf 所在的文件夹 - `--add-driver INF_OR_DIR` 添加额外驱动,填写 .inf 路径,或者 .inf 所在的文件夹
- 需先下载驱动到当前系统 - 需先下载驱动到当前系统
- 可多次设置该参数以添加不同的驱动 - 可多次设置该参数以添加不同的驱动
- `--frpc-toml /path/to/frpc.toml` 添加 frpc 内网穿透 - `--frpc-toml PATH` 添加 frpc 内网穿透,参数填本地路径或 HTTP 链接
- `--hold 2` 在进入 Windows 官方安装程序之前,可以 SSH 登录修改硬盘内容,硬盘挂载在 `/os` - `--hold 1` 仅重启到安装环境,不运行安装,用于 SSH 登录验证网络连通性
- `--hold 2` 用于在进入 Windows 官方安装程序之前SSH 登录修改 `boot.wim``install.wim` 或者其它内容,硬盘挂载在 `/os`
#### 以下驱动会自动按需下载安装,无需手动添加 #### 以下驱动会自动按需下载安装,无需手动添加
@ -488,15 +498,29 @@ Windows Server 2025 SERVERDATACENTER
> Vista (Server 2008) 和 32 位系统可能会缺少驱动 > Vista (Server 2008) 和 32 位系统可能会缺少驱动
> [!WARNING] > [!WARNING]
> 未开启 CSM 的 EFI 机器,无法安装 Windows 7 (Server 2008 R2)
> >
> Hyper-V (Azure) 需选择合适的虚拟机代系 <https://learn.microsoft.com/windows-server/virtualization/hyper-v/plan/should-i-create-a-generation-1-or-2-virtual-machine-in-hyper-v> > 安装 Windows 7 (Server 2008 R2) 时
>
> 1. EFI 引导的机器要开启 CSM
>
> 2. Hyper-V (Azure) 需选择第 1 代虚拟机 <https://learn.microsoft.com/windows-server/virtualization/hyper-v/plan/should-i-create-a-generation-1-or-2-virtual-machine-in-hyper-v>
> [!WARNING] > [!WARNING]
>
> Windows 10 LTSC 2021 中文版镜像 `zh-cn_windows_10_enterprise_ltsc_2021_x64_dvd_033b7312.iso` 的 `wsappx` 进程会长期占用 CPU > Windows 10 LTSC 2021 中文版镜像 `zh-cn_windows_10_enterprise_ltsc_2021_x64_dvd_033b7312.iso` 的 `wsappx` 进程会长期占用 CPU
> >
> 解决方法是更新系统补丁,或者手动安装 `VCLibs` 库 <https://www.google.com/search?q=ltsc+wsappx> > 解决方法是更新系统补丁,或者手动安装 `VCLibs` 库 <https://www.google.com/search?q=ltsc+wsappx>
> [!WARNING]
>
> 在 GCP 上安装 `2022年5月` 和之后发布的 Windows ISO在引导 Windows 安装界面 (PE) 时会不断反复重启。解决方法如下,二选一
>
> 1. 添加 `--force-boot-mode bios` 参数,脚本将以 `BIOS 引导 + MBR 分区表` 方式安装 Windows
>
> (可选) 安装完成后用 `MBR2GPT /convert /allowFullOS` 命令转为 `EFI 引导 + GPT 分区表`
>
> 2. 自制 RAW 镜像并通过 DD 安装
#### ARM 安装 Windows 的注意事项 #### ARM 安装 Windows 的注意事项
大部分 ARM 机器都支持安装最新版 Windows 11 大部分 ARM 机器都支持安装最新版 Windows 11
@ -539,6 +563,21 @@ Windows Server 2025 SERVERDATACENTER
- `--ssh-key /path/to/public_key` - `--ssh-key /path/to/public_key`
- `--ssh-key C:\path\to\public_key` - `--ssh-key C:\path\to\public_key`
## 如何使用旧版本
根据 Bug 守恒定律,修复旧 Bug 的同时会引入新的 Bug
如果遇到新的 Bug可以试下旧版本是否正常
<https://github.com/bin456789/reinstall/commits/main> 右侧找到旧版本的 `commit_id`
```bash
commit_id=xxxxxxx
curl -O https://raw.githubusercontent.com/bin456789/reinstall/$commit_id/reinstall.sh || wget -O ${_##*/} $_
sed -i "/^confhome.*main$/s/main/$commit_id/" reinstall.sh
bash reinstall.sh ...
```
## 如何修改脚本自用 ## 如何修改脚本自用
1. Fork 本仓库 1. Fork 本仓库

View File

@ -6,10 +6,10 @@
# 需要留意 kali initrd 自带的 /preseed.cfg # 需要留意 kali initrd 自带的 /preseed.cfg
# 下面这行语句无效,因为本行后面有反斜杠,前面有空格(安装器认为不算注释)\ # 下面这行语句无效,因为本行后面有反斜杠,前面有空格(安装器认为不算注释)\
d-i debian-installer/locale string en_US d-i debian-installer/locale string en_US.UTF-8
# B.4.1. 本地化 # B.4.1. 本地化
d-i debian-installer/locale string en_US d-i debian-installer/locale string en_US.UTF-8
d-i keyboard-configuration/xkb-keymap select us d-i keyboard-configuration/xkb-keymap select us
# B.4.2. 网络设置 # B.4.2. 网络设置
@ -25,10 +25,10 @@ d-i mirror/country string manual
# B.4.5. 帐号设置 # B.4.5. 帐号设置
d-i passwd/make-user boolean false d-i passwd/make-user boolean false
# 单纯为了跳过设置,实际上是在 partman/early_command 里设置密码preseed/early_command 无法设置密码
# 注意如果用 ssh key 后面还要删除密码 # 注意如果用 ssh key 后面还要删除密码
d-i passwd/root-password password '' # d-i passwd/root-password password ''
d-i passwd/root-password-again password '' # d-i passwd/root-password-again password ''
# d-i passwd/root-password-crypted password ''
# kali 需要下面这行,否则会提示输入用户名 # kali 需要下面这行,否则会提示输入用户名
d-i passwd/root-login boolean true d-i passwd/root-login boolean true
@ -63,6 +63,9 @@ d-i partman-efi/non_efi_system boolean true
# 选择 true 就一直死循环 # 选择 true 就一直死循环
d-i partman-basicfilesystems/no_swap boolean false d-i partman-basicfilesystems/no_swap boolean false
# 分区大小计算
# https://salsa.debian.org/installer-team/partman-base/-/blob/master/lib/base.sh
# 最小值 膨胀权重 最大值 # 最小值 膨胀权重 最大值
# https://salsa.debian.org/installer-team/partman-auto/-/blob/master/recipes/atomic?ref_type=heads # https://salsa.debian.org/installer-team/partman-auto/-/blob/master/recipes/atomic?ref_type=heads
# https://salsa.debian.org/installer-team/partman-auto/-/blob/master/recipes-amd64-efi/atomic?ref_type=heads # https://salsa.debian.org/installer-team/partman-auto/-/blob/master/recipes-amd64-efi/atomic?ref_type=heads
@ -73,6 +76,7 @@ d-i partman-auto/expert_recipe_efi string efi :: \
1 1 -1 $default_filesystem \ 1 1 -1 $default_filesystem \
method{ format } format{ } use_filesystem{ } $default_filesystem{ } mountpoint{ / } . method{ format } format{ } use_filesystem{ } $default_filesystem{ } mountpoint{ / } .
# 大于 2T 会自动用 gpt
# shellcheck disable=SC1083,SC2086,SC2154 # shellcheck disable=SC1083,SC2086,SC2154
d-i partman-auto/expert_recipe_bios string bios :: \ d-i partman-auto/expert_recipe_bios string bios :: \
1 1 1 free \ 1 1 1 free \
@ -99,26 +103,127 @@ d-i pkgsel/upgrade select none
d-i grub-installer/force-efi-extra-removable boolean true d-i grub-installer/force-efi-extra-removable boolean true
# B.4.12. 完成安装 # B.4.12. 完成安装
d-i finish-install/reboot_in_progress note # 由下面的 hold 2 设置
# d-i finish-install/reboot_in_progress note
# B.4.13. 预置其他的软件包 # B.4.13. 预置其他的软件包
# 其他设置 # 其他设置
# d-i anna/standard_modules boolean false # d-i anna/standard_modules boolean false
# d-i anna/choose_modules string network-console # d-i anna/choose_modules string network-console
# d-i network-console/password password 123@@@ # d-i network-console/password password ''
# d-i network-console/password-again password 123@@@ # d-i network-console/password-again password ''
# B.5.1. 安装过程中运行用户命令 # B.5.1. 安装过程中运行用户命令
# 注意所有命令都会合并成一行命令 # 注意所有命令都会合并成一行命令
# 最后的 true; \ 没什么用,只是让 vscode 代码高亮不报错误 # 最后的 true; \ 没什么用,只是让 vscode 代码高亮不报错误
# debian 11+ 才有 websocketd
# 有 /cdrom/simple-cdd 才安装 simple-cdd-profiles # 有 /cdrom/simple-cdd 才安装 simple-cdd-profiles
# 不然安装时 control 脚本会报错: # 不然安装时 control 脚本会报错:
# Loading simple-cdd-profiles failed for unknown reasons # Loading simple-cdd-profiles failed for unknown reasons
# 未下载的组件,无法用 debconf-set需要用 debconf-set-selections
# https://salsa.debian.org/installer-team/network-console/-/blob/master/debian/network-console.postinst?ref_type=heads
# https://salsa.debian.org/installer-team/user-setup/-/blob/master/user-setup-apply?ref_type=heads
# 此时还没有配置源anna-install 会在配置完源后再安装
d-i preseed/early_command string true; \ d-i preseed/early_command string true; \
if [ -d /cdrom/simple-cdd ]; then anna-install simple-cdd-profiles; fi for str in $(grep -wo "extra_[^ ]*" /proc/cmdline | sed 's/^extra_//'); do eval "$str"; done; \
di(){ \
echo "d-i $*" >/tmp/selections.cfg; \
echo "d-i $*" >>/tmp/selections.cfg.all; \
debconf-set-selections /tmp/selections.cfg; \
rm -f /tmp/selections.cfg; \
}; \
run_as_service_with_screen() { \
if ! [ -f /etc/screenrc.bak ]; then \
cp /etc/screenrc /etc/screenrc.bak; \
fi; \
true >/etc/screenrc; \
screen sh -c 'while true; do pidof ${1##*/} || "$@"; sleep 5; done' _ "$@"; \
cp -f /etc/screenrc.bak /etc/screenrc; \
}; \
if [ "$hold" = 1 ]; then \
di auto-install/enable boolean false; \
di debconf/priority select low; \
di partman/early_command string; \
else \
{ \
echo 'Reinstalling...'; \
echo 'Option 1. View logs:'; \
echo ' tail -fn+1 /var/log/syslog'; \
echo 'Option 2. Attach to the installer:'; \
echo ' TERM=screen screen -xp1'; \
} >>/etc/motd; \
mem=$(grep ^MemTotal: /proc/meminfo | { read -r _ y _; echo "$((y / 1024))"; }); \
if command -v websocketd && [ "$mem" -ge 400 ]; then \
for _ in {1..10}; do \
if wget "$confhome/logviewer.html" -O /tmp/index.html; then \
break; \
fi; \
sleep 5; \
done; \
if [ -z "$web_port" ]; then \
web_port=80; \
fi; \
run_as_service_with_screen websocketd --port 80 --loglevel=fatal --staticdir=/tmp \
sh -c "tail -fn+0 /var/log/syslog | tr '\r' '\n' | grep -Fiv -e password -e token" ; \
fi; \
fi; \
if ! [ "$hold" = 2 ]; then \
di finish-install/reboot_in_progress note; \
fi; \
if [ -s /configs/ssh_keys ]; then \
di passwd/root-password-crypted password "''"; \
else \
di passwd/root-password-crypted password "$(cat /configs/password-linux-sha512)"; \
fi; \
mkdir -p /etc/ssh; \
true >/etc/ssh/sshd_config; \
if [ -s /configs/ssh_keys ]; then \
(umask 077; mkdir -p /.ssh; cat /configs/ssh_keys >/.ssh/authorized_keys); \
else \
echo "PermitRootLogin yes" >>/etc/ssh/sshd_config; \
fi; \
if [ -n "$ssh_port" ] && ! [ "$ssh_port" = 22 ]; then \
echo "Port $ssh_port" >>/etc/ssh/sshd_config; \
fi; \
grep -qs ^root: /etc/shadow || echo "root:$(cat /configs/password-linux-sha512):1:0:99999:7:::" >>/etc/shadow; \
grep -qs ^nogroup: /etc/group || echo "nogroup:*:65534:" >>/etc/group; \
grep -qs ^sshd: /etc/passwd || echo "sshd:*:100:65534::/run/sshd:/bin/false" >>/etc/passwd; \
mkdir -p /run/sshd; \
chmod 0755 /run/sshd; \
ssh-keygen -A; \
run_as_service_with_screen /usr/sbin/sshd -D; \
if [ -s /configs/frpc.toml ]; then \
url=$(sh /get-frpc-url.sh linux); \
mkdir -p /usr/local/bin; \
mkdir -p /usr/local/etc/frpc; \
for _ in {1..10}; do \
if wget -O- "$url" | tar xz "*/frpc" -O >/usr/local/bin/frpc; then \
break; \
fi; \
sleep 5; \
done; \
chmod a+x /usr/local/bin/frpc; \
cp /configs/frpc.toml /usr/local/etc/frpc/; \
run_as_service_with_screen /usr/local/bin/frpc -c /usr/local/etc/frpc/frpc.toml; \
fi; \
if [ -d /cdrom/simple-cdd ]; then \
anna-install simple-cdd-profiles; \
fi
# debian 11 initrd 没有 xargs awk # debian 11 initrd 没有 xargs awk
# debian 12 initrd 没有 xargs # debian 12 initrd 没有 xargs
@ -132,10 +237,11 @@ d-i partman/early_command string true; \
true >$postinst; \ true >$postinst; \
swapfile=/target/swapfile; \ swapfile=/target/swapfile; \
mem=$(grep ^MemTotal: /proc/meminfo | { read -r _ y _; echo "$y"; }); \ mem=$(grep ^MemTotal: /proc/meminfo | { read -r _ y _; echo "$((y / 1024))"; }); \
mem=$((mem / 1024)); \
swap_size=$((512 - mem)); \ swap_size=$((512 - mem)); \
[ $swap_size -gt 0 ] && echo "fallocate -l ${swap_size}M $swapfile; mkswap $swapfile; swapon $swapfile" >>$postinst; \ if [ $swap_size -gt 0 ]; then \
echo "fallocate -l ${swap_size}M $swapfile; mkswap $swapfile; swapon $swapfile" >>$postinst; \
fi; \
echo "swapoff -a; rm -f $swapfile" >/usr/lib/finish-install.d/95swapoff; \ echo "swapoff -a; rm -f $swapfile" >/usr/lib/finish-install.d/95swapoff; \
chmod a+x /usr/lib/finish-install.d/95swapoff; \ chmod a+x /usr/lib/finish-install.d/95swapoff; \
@ -152,12 +258,15 @@ d-i partman/early_command string true; \
eths=$(cd /dev/netconf/ && ls); \ eths=$(cd /dev/netconf/ && ls); \
sh /can_use_cloud_kernel.sh "$xda" $eths || debconf-set base-installer/kernel/image "$(debconf-get base-installer/kernel/image | sed 's/-cloud//')"; \ if ! sh /can_use_cloud_kernel.sh "$xda" $eths; then \
debconf-set base-installer/kernel/image "$(debconf-get base-installer/kernel/image | sed 's/-cloud//')"; \
fi; \
[ -d /sys/firmware/efi ] && debconf-set partman-auto/expert_recipe "$(debconf-get partman-auto/expert_recipe_efi)"; \ if [ -d /sys/firmware/efi ]; then \
[ -d /sys/firmware/efi ] || debconf-set partman-auto/expert_recipe "$(debconf-get partman-auto/expert_recipe_bios)"; \ debconf-set partman-auto/expert_recipe "$(debconf-get partman-auto/expert_recipe_efi)"; \
else \
debconf-set passwd/root-password-crypted "$(cat /configs/password-linux-sha512)"; \ debconf-set partman-auto/expert_recipe "$(debconf-get partman-auto/expert_recipe_bios)"; \
fi; \
true >/bin/os-prober true >/bin/os-prober
@ -188,17 +297,11 @@ d-i preseed/late_command string true; \
fi; \ fi; \
if [ -s /configs/frpc.toml ]; then \ if [ -s /configs/frpc.toml ]; then \
url=$(sh /get-frpc-url.sh linux); \
basename=$(echo "$url" | sed 's,.*/,,' | sed 's,\.tar\.gz,,'); \
mkdir -p /target/usr/local/bin; \ mkdir -p /target/usr/local/bin; \
mkdir -p /target/usr/local/etc/frpc; \ mkdir -p /target/usr/local/etc/frpc; \
for i in {1..5}; do \ cp /usr/local/bin/frpc /target/usr/local/bin/; \
wget -O /target/frpc.tar.gz "$url" && break; \ cp /usr/local/etc/frpc/frpc.toml /target/usr/local/etc/frpc/; \
done; \
tar xzf /target/frpc.tar.gz "$basename/frpc" -O >/target/usr/local/bin/frpc; \
rm -f /target/frpc.tar.gzx; \
chmod a+x /target/usr/local/bin/frpc; \ chmod a+x /target/usr/local/bin/frpc; \
cp /configs/frpc.toml /target/usr/local/etc/frpc/; \
cp /frpc.service /target/etc/systemd/system/; \ cp /frpc.service /target/etc/systemd/system/; \
in-target systemctl enable frpc; \ in-target systemctl enable frpc; \
fi; \ fi; \

View File

@ -48,20 +48,39 @@ retry() {
# 用 systemd-analyze plot >a.svg 发现 sys-subsystem-net-devices-enp3s0.device 也是出现在 NetworkManager 之后 # 用 systemd-analyze plot >a.svg 发现 sys-subsystem-net-devices-enp3s0.device 也是出现在 NetworkManager 之后
# 因此需要等待网卡出现 # 因此需要等待网卡出现
get_ethx_by_mac() { get_ethx_by_mac() {
mac=$(echo "$1" | to_lower) retry 10 _get_ethx_by_mac "$@"
retry 10 _get_ethx_by_mac "$mac"
} }
_get_ethx_by_mac() { _get_ethx_by_mac() {
mac=$(echo "$1" | to_lower)
flag=$2
if [ -z "$flag" ]; then
flag=master
fi
if true; then if true; then
# 过滤 azure vf (带 master ethx) if [ "$flag" = master ]; then
ip -o link | grep -i "$mac" | grep -v master | awk '{print $2}' | cut -d: -f1 | grep . # master
return # 过滤 azure vf (带 master ethx)
ip -o link | grep -i "$mac" | grep -v master | awk '{print $2}' | cut -d: -f1 | grep .
else
# slave
# 带 master ethx
ip -o link | grep -i "$mac" | grep -w master | awk '{print $2}' | cut -d: -f1 | grep .
fi
else else
for i in $(cd /sys/class/net && echo *); do for i in $(cd /sys/class/net && echo *); do
if [ "$(cat "/sys/class/net/$i/address")" = "$mac" ]; then if [ "$(cat "/sys/class/net/$i/address")" = "$mac" ]; then
echo "$i" if [ $(($(cat "/sys/class/net/$i/flags") & 0x800)) -ne 0 ]; then
return fact_flag=slave
else
fact_flag=master
fi
if [ "$flag" = "$fact_flag" ]; then
echo "$i"
return
fi
fi fi
done done
return 1 return 1
@ -138,6 +157,23 @@ fix_network_manager() {
# 更改文件名 # 更改文件名
mv "$file" "$proper_file" mv "$file" "$proper_file"
# NM 不会自动忽略 Azure 的 slave 网卡,需手动设置
# azure 文档中的方法不够通用,只适合 azure
# https://learn.microsoft.com/zh-cn/azure/virtual-network/accelerated-networking-overview
# 我们采用红帽的方法
# https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/8/html/configuring_and_managing_networking/configuring-networkmanager-to-ignore-certain-devices_configuring-and-managing-networking
if slave_ethx=$(get_ethx_by_mac "$mac" slave); then
cat >"/etc/NetworkManager/conf.d/99-$slave_ethx-unmanaged.conf" <<EOF
[device-$slave_ethx-unmanaged]
match-device=interface-name:$slave_ethx
managed=0
EOF
fi
# 也可以设置 unmanaged-devices, 但是官方文档不推荐
# https://networkmanager.pages.freedesktop.org/NetworkManager/NetworkManager/NetworkManager.conf.html#:~:text=may%20be%20a-,better%20choice,-.
done done
} }

View File

@ -1,6 +1,6 @@
serverAddr = "YOUR_FRP_SERVER_IP" serverAddr = "11.22.33.44"
serverPort = 7000 serverPort = 7000
auth.token = "YOUR_FRP_TOKEN" auth.token = "123456"
[[proxies]] [[proxies]]
name = "ssh" name = "ssh"

View File

@ -10,7 +10,7 @@ is_in_china() {
} }
is_ipv6_only() { is_ipv6_only() {
! grep -q 1 /dev/netconf/eth*/ipv4_has_internet ! grep -q 1 /dev/netconf/*/ipv4_has_internet
} }
get_frpc_url() { get_frpc_url() {
@ -60,6 +60,7 @@ get_frpc_url() {
mirror=$( mirror=$(
# nju 没有 win7 用的旧版 # nju 没有 win7 用的旧版
# github 不支持 ipv6 # github 不支持 ipv6
# daocloud 加速不支持 ipv6
# jsdelivr 不支持 github releases 文件 # jsdelivr 不支持 github releases 文件
if is_ipv6_only; then if is_ipv6_only; then
if is_need_old_version; then if is_need_old_version; then
@ -71,7 +72,7 @@ get_frpc_url() {
else else
if is_in_china; then if is_in_china; then
if is_need_old_version; then if is_need_old_version; then
echo https://github.com/fatedier/frp/releases/download echo https://files.m.daocloud.io/github.com/fatedier/frp/releases/download
else else
echo https://mirrors.nju.edu.cn/github-release/fatedier/frp echo https://mirrors.nju.edu.cn/github-release/fatedier/frp
fi fi

View File

@ -240,11 +240,17 @@ test_connect() {
test_internet() { test_internet() {
for i in $(seq 5); do for i in $(seq 5); do
echo "Testing Internet Connection. Test $i... " echo "Testing Internet Connection. Test $i... "
if is_need_test_ipv4 && { local current_ipv4_addr; current_ipv4_addr="$(get_first_ipv4_addr | remove_netmask)"; test_connect "$current_ipv4_addr" "$ipv4_dns1" >/dev/null 2>&1 || test_connect "$current_ipv4_addr" "$ipv4_dns2" >/dev/null 2>&1; }; then if is_need_test_ipv4 &&
current_ipv4_addr="$(get_first_ipv4_addr | remove_netmask)" &&
{ test_connect "$current_ipv4_addr" "$ipv4_dns1" ||
test_connect "$current_ipv4_addr" "$ipv4_dns2"; } >/dev/null 2>&1; then
echo "IPv4 has internet." echo "IPv4 has internet."
ipv4_has_internet=true ipv4_has_internet=true
fi fi
if is_need_test_ipv6 && { local current_ipv6_addr; current_ipv6_addr="$(get_first_ipv6_addr | remove_netmask)"; test_connect "$current_ipv6_addr" "$ipv6_dns1" >/dev/null 2>&1 || test_connect "$current_ipv6_addr" "$ipv6_dns2" >/dev/null 2>&1; }; then if is_need_test_ipv6 &&
current_ipv6_addr="$(get_first_ipv6_addr | remove_netmask)" &&
{ test_connect "$current_ipv6_addr" "$ipv6_dns1" ||
test_connect "$current_ipv6_addr" "$ipv6_dns2"; } >/dev/null 2>&1; then
echo "IPv6 has internet." echo "IPv6 has internet."
ipv6_has_internet=true ipv6_has_internet=true
fi fi
@ -339,13 +345,14 @@ EOF
db_progress INFO netcfg/link_detect_progress db_progress INFO netcfg/link_detect_progress
else else
# alpine # alpine
# h3c 移动云电脑使用 udhcpc 会重复提示 sending select无法获得 ipv6因此使用 dhcpcd # h3c 移动云电脑使用 udhcpc 会重复提示 sending select因此添加 timeout 强制结束进程
method=dhcpcd # dhcpcd 会配置租约时间,过期会移除 IP但我们的没有在后台运行 dhcpcd ,因此用 udhcpc
method=udhcpc
case "$method" in case "$method" in
udhcpc) udhcpc)
udhcpc -i "$ethx" -f -q -n || true timeout $DHCP_TIMEOUT udhcpc -i "$ethx" -f -q -n || true
udhcpc6 -i "$ethx" -f -q -n || true timeout $DHCP_TIMEOUT udhcpc6 -i "$ethx" -f -q -n || true
sleep $DNS_FILE_TIMEOUT # 好像不用等待写入 dns但是以防万一 sleep $DNS_FILE_TIMEOUT # 好像不用等待写入 dns但是以防万一
;; ;;
dhcpcd) dhcpcd)

View File

@ -66,6 +66,12 @@
const scrollToBottomButton = document.getElementById('scroll-to-bottom'); const scrollToBottomButton = document.getElementById('scroll-to-bottom');
let shouldScrollToBottom = true; let shouldScrollToBottom = true;
// 缓冲区相关
let messageBuffer = [];
let flushScheduled = false;
const BUFFER_FLUSH_INTERVAL = 100; // 毫秒
const BUFFER_MAX_SIZE = 50; // 最大缓冲消息数
scrollToBottomButton.addEventListener('click', () => { scrollToBottomButton.addEventListener('click', () => {
logContainer.scrollTop = logContainer.scrollHeight; logContainer.scrollTop = logContainer.scrollHeight;
}); });
@ -81,30 +87,71 @@
shouldScrollToBottom = isAtBottom; shouldScrollToBottom = isAtBottom;
}); });
var ws = new ReconnectingWebSocket('ws://' + location.host + '/'); // 刷新缓冲区到 DOM
ws.onopen = function () { function flushBuffer() {
logContainer.textContent += '\nWebSocket Connected.'; if (messageBuffer.length === 0) {
}; flushScheduled = false;
ws.onclose = function () { return;
logContainer.textContent += '\nWebSocket Disconnected.'; }
};
ws.onmessage = function (event) { // 批量更新文本内容
logContainer.textContent += '\n' + event.data; const batchText = messageBuffer.join('\n');
logContainer.textContent += '\n' + batchText;
// 检查状态变化优先级error > done > start
if (batchText.includes('***** ERROR *****')) {
document.body.className = 'error';
} else if (batchText.includes('***** DONE *****')) {
document.body.className = 'done';
} else if (batchText.includes('***** START TRANS *****')) {
document.body.className = '';
}
// 自动滚动
if (shouldScrollToBottom) { if (shouldScrollToBottom) {
logContainer.scrollTop = logContainer.scrollHeight; logContainer.scrollTop = logContainer.scrollHeight;
} }
// 开始/重新开始
if (event.data.includes('***** START TRANS *****')) { // 清空缓冲区
document.body.className = '' messageBuffer = [];
flushScheduled = false;
}
// 调度刷新
function scheduleFlush() {
if (!flushScheduled) {
flushScheduled = true;
requestAnimationFrame(() => {
setTimeout(flushBuffer, BUFFER_FLUSH_INTERVAL);
});
} }
// 错误 }
else if (event.data.includes('***** ERROR *****')) {
document.body.className = 'error' // 添加消息到缓冲区
} function bufferMessage(message) {
// 完成 messageBuffer.push(message);
else if (event.data.includes('***** DONE *****')) {
document.body.className = 'done' // 如果缓冲区满了,立即刷新
if (messageBuffer.length >= BUFFER_MAX_SIZE) {
if (flushScheduled) {
// 取消之前的调度,立即刷新
flushScheduled = false;
}
flushBuffer();
} else {
scheduleFlush();
} }
}
var ws = new ReconnectingWebSocket('ws://' + location.host + '/');
ws.onopen = function () {
bufferMessage('WebSocket Connected.');
};
ws.onclose = function () {
bufferMessage('WebSocket Disconnected.');
};
ws.onmessage = function (event) {
bufferMessage(event.data);
}; };
</script> </script>
</body> </body>

View File

@ -131,6 +131,13 @@ call :check_cygwin_installed || (
set dir=/sourceware/cygwin set dir=/sourceware/cygwin
) )
rem daocloud 加速有 90 天缓存,且不支持 IPv6
rem https://github.com/DaoCloud/public-binary-files-mirror
rem 无法用查询字符串强制刷新缓存
rem https://files.m.daocloud.io/www.cloudflare.com/cdn-cgi/trace?a=1
rem https://files.m.daocloud.io/www.cloudflare.com/cdn-cgi/trace?b=2
rem 也就无法用 https://www.cygwin.com/setup-x86_64.exe?xxx=20250101 强制每天刷新缓存
rem 下载 Cygwin rem 下载 Cygwin
if not exist setup-!CygwinArch!.exe ( if not exist setup-!CygwinArch!.exe (
call :download http://www.cygwin.com/setup-!CygwinArch!.exe %~dp0setup-!CygwinArch!.exe || goto :download_failed call :download http://www.cygwin.com/setup-!CygwinArch!.exe %~dp0setup-!CygwinArch!.exe || goto :download_failed
@ -195,7 +202,7 @@ rem bitsadmin /transfer "%~3" /priority foreground %~1 %~2
:download :download
rem certutil 会被 windows Defender 报毒 rem certutil 会被 windows Defender 报毒
rem windows server 2019 要用第二条 certutil 命令 rem windows server 2019 要用第二条 certutil 命令
echo Download: %~1 %~2 echo Downloading: %~1 %~2
del /q "%~2" 2>nul del /q "%~2" 2>nul
if exist "%~2" (echo Cannot delete %~2 & exit /b 1) if exist "%~2" (echo Cannot delete %~2 & exit /b 1)

View File

@ -7,11 +7,8 @@ confhome=https://raw.githubusercontent.com/bin456789/reinstall/main
confhome_cn=https://cnb.cool/bin456789/reinstall/-/git/raw/main confhome_cn=https://cnb.cool/bin456789/reinstall/-/git/raw/main
# confhome_cn=https://www.ghproxy.cc/https://raw.githubusercontent.com/bin456789/reinstall/main # confhome_cn=https://www.ghproxy.cc/https://raw.githubusercontent.com/bin456789/reinstall/main
# 默认密码
DEFAULT_PASSWORD=123@@@
# 用于判断 reinstall.sh 和 trans.sh 是否兼容 # 用于判断 reinstall.sh 和 trans.sh 是否兼容
SCRIPT_VERSION=4BACD833-A585-23BA-6CBB-9AA4E08E0003 SCRIPT_VERSION=4BACD833-A585-23BA-6CBB-9AA4E08E0004
# 记录要用到的 windows 程序,运行时输出删除 \r # 记录要用到的 windows 程序,运行时输出删除 \r
WINDOWS_EXES='cmd powershell wmic reg diskpart netsh bcdedit mountvol' WINDOWS_EXES='cmd powershell wmic reg diskpart netsh bcdedit mountvol'
@ -25,6 +22,22 @@ export LC_ALL=C
# 不要漏了最后的 $PATH否则会找不到 windows 系统程序例如 diskpart # 不要漏了最后的 $PATH否则会找不到 windows 系统程序例如 diskpart
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH
# 如果不是 bash 的话,继续执行会有语法错误,因此在这里判断是否 bash
if [ -z "$BASH" ]; then
if [ -f /etc/alpine-release ]; then
if ! apk add bash; then
echo "Error while install bash." >&2
exit 1
fi
fi
if command -v bash >/dev/null; then
exec bash "$0" "$@"
else
echo "Please run this script with bash." >&2
exit 1
fi
fi
# 记录日志,过滤含有 password 的行 # 记录日志,过滤含有 password 的行
exec > >(tee >(grep -iv password >>/reinstall.log)) 2>&1 exec > >(tee >(grep -iv password >>/reinstall.log)) 2>&1
THIS_SCRIPT=$(readlink -f "$0") THIS_SCRIPT=$(readlink -f "$0")
@ -48,21 +61,21 @@ usage_and_exit() {
Usage: $reinstall_____ anolis 7|8|23 Usage: $reinstall_____ anolis 7|8|23
opencloudos 8|9|23 opencloudos 8|9|23
rocky 8|9|10 rocky 8|9|10
oracle 8|9 oracle 8|9|10
almalinux 8|9|10 almalinux 8|9|10
centos 9|10 centos 9|10
fedora 41|42 fnos 1
nixos 25.05 nixos 25.11
fedora 42|43
debian 9|10|11|12|13 debian 9|10|11|12|13
opensuse 15.6|tumbleweed alpine 3.20|3.21|3.22|3.23
alpine 3.19|3.20|3.21|3.22 opensuse 15.6|16.0|tumbleweed
openeuler 20.03|22.03|24.03|25.03 openeuler 20.03|22.03|24.03|25.09
ubuntu 16.04|18.04|20.04|22.04|24.04|25.04 [--minimal] ubuntu 16.04|18.04|20.04|22.04|24.04|25.10 [--minimal]
kali kali
arch arch
gentoo gentoo
aosc aosc
fnos
redhat --img="http://access.cdn.redhat.com/xxx.qcow2" redhat --img="http://access.cdn.redhat.com/xxx.qcow2"
dd --img="http://xxx.com/yyy.zzz" (raw image stores in raw/vhd/tar/gz/xz/zst) dd --img="http://xxx.com/yyy.zzz" (raw image stores in raw/vhd/tar/gz/xz/zst)
windows --image-name="windows xxx yyy" --lang=xx-yy windows --image-name="windows xxx yyy" --lang=xx-yy
@ -74,7 +87,7 @@ Usage: $reinstall_____ anolis 7|8|23
[--ssh-key KEY] [--ssh-key KEY]
[--ssh-port PORT] [--ssh-port PORT]
[--web-port PORT] [--web-port PORT]
[--frpc-toml TOML] [--frpc-toml PATH]
For Windows Only: For Windows Only:
[--allow-ping] [--allow-ping]
@ -126,14 +139,35 @@ error_and_exit() {
exit 1 exit 1
} }
show_dd_password_tips() {
warn false "
This password is only used for SSH access to view logs during the installation.
Password of the image will NOT modify.
密码仅用于安装过程中通过 SSH 查看日志。
镜像的密码不会被修改。
"
}
show_url_in_args() {
while [ $# -gt 0 ]; do
case "$1" in
[Hh][Tt][Tt][Pp][Ss]://* | [Hh][Tt][Tt][Pp]://* | [Mm][Aa][Gg][Nn][Ee][Tt]:*) echo "$1" ;;
esac
shift
done
}
curl() { curl() {
is_have_cmd curl || install_pkg curl is_have_cmd curl || install_pkg curl
# 显示 url
show_url_in_args "$@" >&2
# 添加 -f, --fail不然 404 退出码也为0 # 添加 -f, --fail不然 404 退出码也为0
# 32位 cygwin 已停止更新,证书可能有问题,先添加 --insecure # 32位 cygwin 已停止更新,证书可能有问题,先添加 --insecure
# centos 7 curl 不支持 --retry-connrefused --retry-all-errors # centos 7 curl 不支持 --retry-connrefused --retry-all-errors
# 因此手动 retry # 因此手动 retry
grep -o 'http[^ ]*' <<<"$@" >&2
for i in $(seq 5); do for i in $(seq 5); do
if command curl --insecure --connect-timeout 10 -f "$@"; then if command curl --insecure --connect-timeout 10 -f "$@"; then
return return
@ -280,11 +314,21 @@ get_function_content() {
} }
insert_into_file() { insert_into_file() {
file=$1 local file=$1
location=$2 local location=$2
regex_to_find=$3 local regex_to_find=$3
shift 3
line_num=$(grep -E -n "$regex_to_find" "$file" | cut -d: -f1) if ! [ -f "$file" ]; then
error_and_exit "File not found: $file"
fi
# 默认 grep -E
if [ $# -eq 0 ]; then
set -- -E
fi
line_num=$(grep "$@" -n "$regex_to_find" "$file" | cut -d: -f1)
found_count=$(echo "$line_num" | wc -l) found_count=$(echo "$line_num" | wc -l)
if [ ! "$found_count" -eq 1 ]; then if [ ! "$found_count" -eq 1 ]; then
@ -813,30 +857,22 @@ is_have_arm_version() {
case "$version" in case "$version" in
10) 10)
case "$edition" in case "$edition" in
pro | education | enterprise | 'pro education' | 'pro for workstations') return ;; home | 'home single language' | pro | education | enterprise | 'pro education' | 'pro for workstations') return ;;
'iot enterprise') return ;; 'iot enterprise') return ;;
# arm ltsc 只有 2021 有 iso
'enterprise ltsc 2021' | 'iot enterprise ltsc 2021') return ;; 'enterprise ltsc 2021' | 'iot enterprise ltsc 2021') return ;;
esac esac
;; ;;
11) 11) return ;;
case "$edition" in
pro | education | enterprise | 'pro education' | 'pro for workstations') return ;;
'iot enterprise' | 'iot enterprise subscription') return ;;
'enterprise ltsc 2024' | 'iot enterprise ltsc 2024' | 'iot enterprise ltsc 2024 subscription') return ;;
esac
;;
esac esac
return 1 return 1
} }
find_windows_iso() { find_windows_iso() {
parse_windows_image_name || error_and_exit "--image-name wrong: $image_name" parse_windows_image_name || error_and_exit "--image-name wrong: $image_name"
if ! [ "$version" = 8.1 ] && [ -z "$edition" ]; then if ! { [ "$version" = 8 ] || [ "$version" = 8.1 ]; } && [ -z "$edition" ]; then
error_and_exit "Edition is not set." error_and_exit "Edition is not set."
fi fi
if [ "$basearch" = 'aarch64' ] && ! is_have_arm_version; then
error_and_exit "No ARM iso for this Windows Version."
fi
if [ -z "$lang" ]; then if [ -z "$lang" ]; then
lang=en-us lang=en-us
@ -883,7 +919,8 @@ get_windows_iso_link() {
x86) echo _ ;; x86) echo _ ;;
esac esac
;; ;;
homebasic | homepremium | business | ultimate) echo _ ;; homebasic | homepremium | ultimate) echo _ ;;
business | enterprise) echo "$edition" ;;
esac esac
;; ;;
7) 7)
@ -902,17 +939,22 @@ get_windows_iso_link() {
professional | enterprise | ultimate) echo "$edition" ;; professional | enterprise | ultimate) echo "$edition" ;;
esac esac
;; ;;
# massgrave 不提供 windows 8 下载 8 | 8.1)
8.1)
case "$edition" in case "$edition" in
'') echo _ ;; # windows 8.1 core '') echo _ ;; # windows 8.x core
pro | enterprise) echo "$edition" ;; pro | enterprise) echo "$edition" ;;
esac esac
;; ;;
10) 10)
case "$edition" in case "$edition" in
home | 'home single language') echo consumer ;; home | 'home single language') echo consumer ;;
pro | education | enterprise | 'pro education' | 'pro for workstations') echo business ;; pro | enterprise) echo business ;;
education | 'pro education' | 'pro for workstations')
case "$arch_win" in
arm64) echo consumer ;;
x64) echo business ;; # iso 更小
esac
;;
# iot # iot
'iot enterprise') echo 'iot enterprise' ;; 'iot enterprise') echo 'iot enterprise' ;;
# iot ltsc # iot ltsc
@ -929,13 +971,23 @@ get_windows_iso_link() {
esac esac
;; ;;
11) 11)
# arm business iso 都没有 education, pro education, pro for workstations
# 即使它的名字包含 EDU
# SW_DVD9_Win_Pro_10_22H2.31_Arm64_English_Pro_Ent_EDU_N_MLF_X24-05074.ISO
# en-us_windows_11_business_editions_version_25h2_arm64_dvd_8afc9b39.iso
case "$edition" in case "$edition" in
home | 'home single language') echo consumer ;; home | 'home single language') echo consumer ;;
pro | education | enterprise | 'pro education' | 'pro for workstations') echo business ;; pro | enterprise) echo business ;;
education | 'pro education' | 'pro for workstations')
case "$arch_win" in
arm64) echo consumer ;;
x64) echo business ;; # iso 更小
esac
;;
# iot # iot
'iot enterprise' | 'iot enterprise subscription') echo 'iot enterprise' ;; 'iot enterprise' | 'iot enterprise subscription') echo 'iot enterprise' ;;
# iot ltsc # iot ltsc
'iot enterprise ltsc 2024' | 'iot enterprise ltsc 2024 subscription') echo 'iot enterprise ltsc 2024' ;; 'iot enterprise ltsc 2024' | 'iot enterprise subscription ltsc 2024') echo 'iot enterprise ltsc 2024' ;;
# ltsc # ltsc
'enterprise ltsc 2024') 'enterprise ltsc 2024')
# arm64 的 enterprise ltsc 2024 要下载 iot enterprise ltsc 2024 iso # arm64 的 enterprise ltsc 2024 要下载 iot enterprise ltsc 2024 iso
@ -960,8 +1012,11 @@ get_windows_iso_link() {
esac esac
} }
# 8.1 和 11 arm 没有每月发布 iso # msdl 没有每月发布 iso
# 因此优先从 msdl 下载 # msdl 只有 consumer 版本,因此里面的 pro 版本不是 vl 版
# 8.1 没有每月发布的 iso因此优先从 msdl 下载
# win10 22h2 arm 有每月发布的 iso因此不从 msdl 下载
# win10/11 ltsc 没有每月发布的 iso但是 msdl 没有 ltsc 版本
get_label_msdl() { get_label_msdl() {
case "$version" in case "$version" in
8.1) 8.1)
@ -969,15 +1024,6 @@ get_windows_iso_link() {
'' | pro) echo _ ;; '' | pro) echo _ ;;
esac esac
;; ;;
11)
case "$edition" in
home | 'home single language' | pro | education | 'pro education' | 'pro for workstations')
case "$arch_win" in
arm64) echo _ ;;
esac
;;
esac
;;
esac esac
} }
@ -990,7 +1036,7 @@ get_windows_iso_link() {
echo server echo server
else else
case "$version" in case "$version" in
vista | 7 | 8.1 | 10 | 11) vista | 7 | 8 | 8.1 | 10 | 11)
echo "$version" echo "$version"
;; ;;
esac esac
@ -1024,14 +1070,26 @@ get_windows_iso_link() {
echo "List: $page_url" echo "List: $page_url"
echo echo
# 先判断是否能自动查找该版本
# 再判断是否支持 arm
# 这样可以在输入错误 Edition 时例如 windows 11 enterprise ltsc 2021
# 显示名称错误,而不是显示该版本不支持 arm
if [ -z "$page" ] || { [ -z "$label_msdn" ] && [ -z "$label_msdl" ] && [ -z "$label_vlsc" ]; }; then if [ -z "$page" ] || { [ -z "$label_msdn" ] && [ -z "$label_msdl" ] && [ -z "$label_vlsc" ]; }; then
error_and_exit "Not support find this iso. Check if --image-name is wrong. If not, set --iso manually." error_and_exit "Not support find this iso. Check if --image-name is wrong. Or set --iso manually."
fi
if [ "$basearch" = aarch64 ] && ! is_have_arm_version; then
error_and_exit "No ARM iso for this Windows Version or Edition."
fi fi
if [ -n "$label_msdl" ]; then if [ -n "$label_msdl" ]; then
iso=$(curl -L "$page_url" | grep -ioP 'https://.*?#[0-9]+' | head -1 | grep .) iso=$(curl -L "$page_url" | grep -ioP 'https://[^ ]+?#[0-9]+' | head -1 | grep .)
else else
curl -L "$page_url" | grep -ioP 'https://.*?.(iso|img)' >$tmp/win.list curl -L "$page_url" |
tr -d '\n' | sed -e 's,<a ,\n<a ,g' -e 's,</a>,</a>\n,g' | # 使每个 <a></a> 占一行
grep -Ei '\.(iso|img)</a>$' | # 找出是 iso 或 img 的行
sed -E 's,<a href="?([^" ]+)"?.+>(.+)</a>,\2 \1,' >$tmp/win.list # 提取文件名和链接
# 如果不是 ltsc ,应该先去除 ltsc 链接,否则最终链接有 ltsc 的 # 如果不是 ltsc ,应该先去除 ltsc 链接,否则最终链接有 ltsc 的
# 例如查找 windows 10 iot enterprise会得到 # 例如查找 windows 10 iot enterprise会得到
@ -1049,10 +1107,14 @@ get_windows_iso_link() {
} }
get_shortest_line() { get_shortest_line() {
# awk '{print length($0), $0}' | sort -n | head -1 | awk '{print $2}'
awk '(NR == 1 || length($0) < length(shortest)) { shortest = $0 } END { print shortest }' awk '(NR == 1 || length($0) < length(shortest)) { shortest = $0 } END { print shortest }'
} }
get_shortest_line_by_field() {
local field=$1
awk "(NR == 1 || length(\$$field) < length(field)) { line = \$0; field = \$$field } END { print line }"
}
get_windows_iso_link_inner() { get_windows_iso_link_inner() {
regexs=() regexs=()
@ -1084,7 +1146,9 @@ get_windows_iso_link_inner() {
regex=${regex// /_} regex=${regex// /_}
echo "looking for: $regex" >&2 echo "looking for: $regex" >&2
if iso=$(grep -Ei "/$regex" "$tmp/win.list" | get_shortest_line | grep .); then if line=$(grep -Ei "^$regex " "$tmp/win.list" | get_shortest_line_by_field 1 | grep .) &&
iso=$(awk '{print $2}' <<<"$line" | grep .); then
echo "Selected: $line" >&2
return return
fi fi
done done
@ -1130,6 +1194,10 @@ setos() {
[ "$releasever" -le 10 ] [ "$releasever" -le 10 ]
} }
if [ "$releasever" -le 9 ] && [ "$basearch" = aarch64 ]; then
error_and_exit "Debian $releasever ELTS does not support aarch64."
fi
# 用此标记要是否 elts, 用于安装后修改 elts/etls-cn 源 # 用此标记要是否 elts, 用于安装后修改 elts/etls-cn 源
# shellcheck disable=SC2034 # shellcheck disable=SC2034
is_debian_elts && elts=1 || elts=0 is_debian_elts && elts=1 || elts=0
@ -1248,6 +1316,7 @@ Continue?
eval ${step}_vmlinuz=$mirror/linux eval ${step}_vmlinuz=$mirror/linux
eval ${step}_initrd=$mirror/initrd.gz eval ${step}_initrd=$mirror/initrd.gz
eval ${step}_ks=$confhome/debian.cfg eval ${step}_ks=$confhome/debian.cfg
eval ${step}_deb_mirror=$hostname/kali
eval ${step}_udeb_mirror=$hostname/kali eval ${step}_udeb_mirror=$hostname/kali
eval ${step}_codename=$codename eval ${step}_codename=$codename
eval ${step}_kernel=linux-image$flavour-$basearch_alt eval ${step}_kernel=linux-image$flavour-$basearch_alt
@ -1262,7 +1331,7 @@ Continue?
20.04) codename=focal ;; 20.04) codename=focal ;;
22.04) codename=jammy ;; 22.04) codename=jammy ;;
24.04) codename=noble ;; 24.04) codename=noble ;;
25.04) codename=plucky ;; # non-lts 25.10) codename=questing ;; # non-lts
esac esac
if is_use_cloud_image; then if is_use_cloud_image; then
@ -1436,32 +1505,25 @@ Continue?
else else
# leap # leap
dir=distribution/leap/$releasever/appliances dir=distribution/leap/$releasever/appliances
if [ "$releasever" = 15.6 ]; then case "$releasever" in
file=openSUSE-Leap-$releasever-Minimal-VM.$basearch-Cloud.qcow2 15.6) file=openSUSE-Leap-$releasever-Minimal-VM.$basearch-Cloud.qcow2 ;;
# https://build.opensuse.org/projects/Virtualization:Appliances:Images:openSUSE-Leap-15.6/packages/kiwi-templates-Minimal/files/Minimal.kiwi 16.0) file=Leap-$releasever-Minimal-VM.$basearch-Cloud.qcow2 ;;
# https://build.opensuse.org/projects/Virtualization:Appliances:Images:openSUSE-Tumbleweed/packages/kiwi-templates-Minimal/files/Minimal.kiwi # 16.0) file=Leap-$releasever-Minimal-VM.$basearch-kvm$(if [ "$basearch" = x86_64 ]; then echo '-and-xen'; fi).qcow2 ;;
# 有专门的kvm镜像openSUSE-Leap-15.5-Minimal-VM.x86_64-kvm-and-xen.qcow2里面没有cloud-init esac
# file=openSUSE-Leap-15.5-Minimal-VM.x86_64-kvm-and-xen.qcow2
else
# https://src.opensuse.org/openSUSE/Leap/raw/branch/16.0/Leap/Leap.kiwi
# Default 比 Base 多了以下组件
# <namedCollection name="salt_minion" />
# <package name="patterns-base-salt_minion" />
# <namedCollection name="kvm_host" />
# <package name="patterns-base-kvm_host" />
# <package name="lzop" />
# <package name="wpa_supplicant" arch="x86_64,aarch64" />
# <package name="k3s-install" />
# file=Leap.x86_64-Default.raw.xz # https://src.opensuse.org/openSUSE/Leap-Images/src/branch/leap-16.0/kiwi-templates-Minimal/Minimal.kiwi
file=Leap.x86_64-Base.raw.xz # https://build.opensuse.org/projects/Virtualization:Appliances:Images:openSUSE-Leap-15.6/packages/kiwi-templates-Minimal/files/Minimal.kiwi
fi # https://build.opensuse.org/projects/Virtualization:Appliances:Images:openSUSE-Tumbleweed/packages/kiwi-templates-Minimal/files/Minimal.kiwi
# 有专门的kvm镜像openSUSE-Leap-15.5-Minimal-VM.x86_64-kvm-and-xen.qcow2里面没有cloud-init
# file=openSUSE-Leap-15.5-Minimal-VM.x86_64-kvm-and-xen.qcow2
fi fi
eval ${step}_img=$mirror/$dir/$file eval ${step}_img=$mirror/$dir/$file
} }
setos_windows() { setos_windows() {
auto_find_iso=false
if [ -z "$iso" ]; then if [ -z "$iso" ]; then
auto_find_iso=true
# 查找时将 windows longhorn serverdatacenter 改成 windows server 2008 serverdatacenter # 查找时将 windows longhorn serverdatacenter 改成 windows server 2008 serverdatacenter
image_name=${image_name/windows longhorn server/windows server 2008 server} image_name=${image_name/windows longhorn server/windows server 2008 server}
echo "iso url is not set. Attempting to find it automatically." echo "iso url is not set. Attempting to find it automatically."
@ -1476,27 +1538,32 @@ Continue?
if [[ "$iso" = magnet:* ]]; then if [[ "$iso" = magnet:* ]]; then
: # 不测试磁力链接 : # 不测试磁力链接
else else
# 需要用户输入 massgrave.dev 直链 iso_is_tested=false
if grep -Eiq '\.massgrave\.dev/.*\.(iso|img)$' <<<"$iso" || if $auto_find_iso; then
grep -Eiq '\.gravesoft\.dev/#[0-9]+$' <<<"$iso"; then if test_url_grace "$iso" iso 2>/dev/null; then
info "Set Direct link" iso_is_tested=true
# MobaXterm 不支持 else
# printf '\e]8;;http://example.com\e\\This is a link\e]8;;\e\\\n' # 需要用户输入 massgrave.dev 直链
info "Set Direct link"
# MobaXterm 不支持
# printf '\e]8;;http://example.com\e\\This is a link\e]8;;\e\\\n'
# MobaXterm 不显示为超链接 # MobaXterm 不显示为超链接
# info false "请在浏览器中打开 $iso 获取直链并粘贴到这里。" # info false "请在浏览器中打开 $iso 获取直链并粘贴到这里。"
# info false "Please open $iso in browser to get the direct link and paste it here." # info false "Please open $iso in browser to get the direct link and paste it here."
echo "请在浏览器中打开 $iso 获取直链并粘贴到这里。" echo "请在浏览器中打开 $iso 获取直链并粘贴到这里。"
echo "Please open $iso in browser to get the direct link and paste it here." echo "Please open $iso in browser to get the direct link and paste it here."
IFS= read -r -p "Direct Link: " iso IFS= read -r -p "Direct Link: " iso
if [ -z "$iso" ]; then if [ -z "$iso" ]; then
error_and_exit "ISO Link is empty." error_and_exit "ISO Link is empty."
fi
fi fi
fi fi
# 测试是否是 iso if ! $iso_is_tested; then
test_url "$iso" iso test_url "$iso" iso
fi
# 判断 iso 架构是否兼容 # 判断 iso 架构是否兼容
# https://gitlab.com/libosinfo/osinfo-db/-/tree/main/data/os/microsoft.com?ref_type=heads # https://gitlab.com/libosinfo/osinfo-db/-/tree/main/data/os/microsoft.com?ref_type=heads
@ -1571,15 +1638,13 @@ Continue with DD?
} }
setos_fnos() { setos_fnos() {
if [ "$basearch" = aarch64 ]; then
error_and_exit "FNOS not supports ARM."
fi
# 系统盘大小 # 系统盘大小
min=8 min=8
default=8 default=8
echo "请输入系统分区大小,最小 $min GB但可能无法更新系统。"
echo "Please input System Partition Size. Minimal is $min GB but may not be able to do system updates."
while true; do while true; do
IFS= read -r -p "Type System Partition Size in GB. Minimal $min GB. [$default]: " input IFS= read -r -p "Size in GB [$default]: " input
input=${input:-$default} input=${input:-$default}
if ! { is_digit "$input" && [ "$input" -ge "$min" ]; }; then if ! { is_digit "$input" && [ "$input" -ge "$min" ]; }; then
error "Invalid Size. Please Try again." error "Invalid Size. Please Try again."
@ -1589,16 +1654,25 @@ Continue with DD?
fi fi
done done
iso=$(curl -L https://fnnas.com/ | grep -o 'https://[^"]*\.iso' | head -1 | grep .) if [ "$basearch" = aarch64 ]; then
if [ -z "$iso" ]; then
IFS= read -r -p "ISO Link: " iso
if [ -z "$iso" ]; then
error_and_exit "ISO Link is empty."
fi
fi
else
iso=$(curl -L https://fnnas.com/ | grep -o -m1 'https://[^"]*\.iso')
# curl 7.82.0+ # curl 7.82.0+
# curl -L --json '{"url":"'$iso'"}' https://www.fnnas.com/api/download-sign # curl -L --json '{"url":"'$iso'"}' https://www.fnnas.com/api/download-sign
iso=$(curl -L \ iso=$(curl -L \
-d '{"url":"'$iso'"}' \ -d '{"url":"'$iso'"}' \
-H 'Content-Type: application/json' \ -H 'Content-Type: application/json' \
https://www.fnnas.com/api/download-sign | https://www.fnnas.com/api/download-sign |
grep -o 'https://[^"]*') grep -o 'https://[^"]*')
fi
test_url "$iso" iso test_url "$iso" iso
eval "${step}_iso='$iso'" eval "${step}_iso='$iso'"
@ -1629,7 +1703,9 @@ Continue with DD?
fi fi
elarch=$basearch elarch=$basearch
if [ "$distro" = almalinux ] && [ "$basearch" = x86_64 ] && ! is_cpu_supports_x86_64_v3; then if [ "$basearch" = x86_64 ] &&
[ "$distro" = almalinux ] && [ "$releasever" -ge 10 ] &&
! is_cpu_supports_x86_64_v3; then
elarch=x86_64_v2 elarch=x86_64_v2
fi fi
@ -1864,20 +1940,20 @@ verify_os_name() {
'opencloudos 8|9|23' \ 'opencloudos 8|9|23' \
'almalinux 8|9|10' \ 'almalinux 8|9|10' \
'rocky 8|9|10' \ 'rocky 8|9|10' \
'oracle 8|9' \ 'oracle 8|9|10' \
'fedora 41|42' \ 'fnos 1' \
'nixos 25.05' \ 'fedora 42|43' \
'nixos 25.11' \
'debian 9|10|11|12|13' \ 'debian 9|10|11|12|13' \
'opensuse 15.6|16.0|tumbleweed' \ 'opensuse 15.6|16.0|tumbleweed' \
'alpine 3.19|3.20|3.21|3.22' \ 'alpine 3.20|3.21|3.22|3.23' \
'openeuler 20.03|22.03|24.03|25.03' \ 'openeuler 20.03|22.03|24.03|25.09' \
'ubuntu 16.04|18.04|20.04|22.04|24.04|25.04' \ 'ubuntu 16.04|18.04|20.04|22.04|24.04|25.10' \
'redhat' \ 'redhat' \
'kali' \ 'kali' \
'arch' \ 'arch' \
'gentoo' \ 'gentoo' \
'aosc' \ 'aosc' \
'fnos' \
'windows' \ 'windows' \
'dd' \ 'dd' \
'netboot.xyz'; do 'netboot.xyz'; do
@ -1931,8 +2007,7 @@ install_pkg() {
# 因为可能装了多种包管理器 # 因为可能装了多种包管理器
if [ -f /etc/os-release ]; then if [ -f /etc/os-release ]; then
# shellcheck source=/dev/null # shellcheck source=/dev/null
. /etc/os-release for id in $({ . /etc/os-release && echo $ID $ID_LIKE; }); do
for id in $ID $ID_LIKE; do
# https://github.com/chef/os_release # https://github.com/chef/os_release
case "$id" in case "$id" in
fedora | centos | rhel) is_have_cmd dnf && pkg_mgr=dnf || pkg_mgr=yum ;; fedora | centos | rhel) is_have_cmd dnf && pkg_mgr=dnf || pkg_mgr=yum ;;
@ -2288,6 +2363,10 @@ del_empty_lines() {
sed '/^[[:space:]]*$/d' sed '/^[[:space:]]*$/d'
} }
del_comment_lines() {
sed '/^[[:space:]]*#/d'
}
trim() { trim() {
# sed -E -e 's/^[[:space:]]+//' -e 's/[[:space:]]+$//' # sed -E -e 's/^[[:space:]]+//' -e 's/[[:space:]]+$//'
sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
@ -2295,16 +2374,23 @@ trim() {
prompt_password() { prompt_password() {
info "prompt password" info "prompt password"
warn false "Leave blank to use a random password."
warn false "不填写则使用随机密码"
while true; do while true; do
IFS= read -r -p "Password [$DEFAULT_PASSWORD]: " password IFS= read -r -p "Password: " password
IFS= read -r -p "Retype password [$DEFAULT_PASSWORD]: " password_confirm if [ -n "$password" ]; then
password=${password:-$DEFAULT_PASSWORD} IFS= read -r -p "Retype password: " password_confirm
password_confirm=${password_confirm:-$DEFAULT_PASSWORD} if [ "$password" = "$password_confirm" ]; then
if [ -z "$password" ]; then break
error "Passwords is empty. Try again." else
elif [ "$password" != "$password_confirm" ]; then error "Passwords don't match. Try again."
error "Passwords don't match. Try again." fi
else else
# 特殊字符列表
# https://learn.microsoft.com/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/hh994562(v=ws.11)
# 有的机器运行 centos 7 ,用 /dev/random 产生 16 位密码,开启了 rngd 也要 5 秒,关闭了 rngd 则长期阻塞
chars=\''A-Za-z0-9~!@#$%^&*_=+`|(){}[]:;"<>,.?/-'
password=$(tr -dc "$chars" </dev/urandom | head -c16)
break break
fi fi
done done
@ -2763,7 +2849,8 @@ install_grub_linux_efi() {
info 'download grub efi' info 'download grub efi'
# fedora 39 的 efi 无法识别 opensuse tumbleweed 的 xfs # fedora 39 的 efi 无法识别 opensuse tumbleweed 的 xfs
efi_distro=fedora efi_distro=opensuse
grub_efi=$(get_grub_efi_filename) grub_efi=$(get_grub_efi_filename)
# 不要用 download.opensuse.org 和 download.fedoraproject.org # 不要用 download.opensuse.org 和 download.fedoraproject.org
@ -2778,6 +2865,7 @@ install_grub_linux_efi() {
# dl.fedoraproject.org 不支持 ipv6 # dl.fedoraproject.org 不支持 ipv6
if [ "$efi_distro" = fedora ]; then if [ "$efi_distro" = fedora ]; then
# fedora 43 efi 在 vultr 无法引导 debain 9/10 netboot
fedora_ver=$(get_latest_distro_releasever fedora) fedora_ver=$(get_latest_distro_releasever fedora)
if is_in_china; then if is_in_china; then
@ -2963,7 +3051,7 @@ build_extra_cmdline() {
# 会将 extra.xxx=yyy 写入新系统的 /etc/modprobe.d/local.conf # 会将 extra.xxx=yyy 写入新系统的 /etc/modprobe.d/local.conf
# https://answers.launchpad.net/ubuntu/+question/249456 # https://answers.launchpad.net/ubuntu/+question/249456
# https://salsa.debian.org/installer-team/rootskel/-/blob/master/src/lib/debian-installer-startup.d/S02module-params?ref_type=heads # https://salsa.debian.org/installer-team/rootskel/-/blob/master/src/lib/debian-installer-startup.d/S02module-params?ref_type=heads
for key in confhome hold force force_cn force_old_windows_setup cloud_image main_disk \ for key in confhome hold force_boot_mode force_cn force_old_windows_setup cloud_image main_disk \
elts deb_mirror \ elts deb_mirror \
ssh_port rdp_port web_port allow_ping; do ssh_port rdp_port web_port allow_ping; do
value=${!key} value=${!key}
@ -3011,7 +3099,11 @@ build_nextos_cmdline() {
if [ $nextos_distro = alpine ]; then if [ $nextos_distro = alpine ]; then
nextos_cmdline="alpine_repo=$nextos_repo modloop=$nextos_modloop" nextos_cmdline="alpine_repo=$nextos_repo modloop=$nextos_modloop"
elif is_distro_like_debian $nextos_distro; then elif is_distro_like_debian $nextos_distro; then
# 设置分辨率为800*600防止分辨率过高 ssh screen attach 后无法全部显示
# iso 默认有 vga=788
# 如果要设置位数: video=800x600-16
nextos_cmdline="lowmem/low=1 auto=true priority=critical" nextos_cmdline="lowmem/low=1 auto=true priority=critical"
# nextos_cmdline+=" vga=788 video=800x600"
nextos_cmdline+=" url=$nextos_ks" nextos_cmdline+=" url=$nextos_ks"
nextos_cmdline+=" mirror/http/hostname=${nextos_udeb_mirror%/*}" nextos_cmdline+=" mirror/http/hostname=${nextos_udeb_mirror%/*}"
nextos_cmdline+=" mirror/http/directory=/${nextos_udeb_mirror##*/}" nextos_cmdline+=" mirror/http/directory=/${nextos_udeb_mirror##*/}"
@ -3076,9 +3168,9 @@ mkdir_clear() {
# 再次运行时,有可能 mount 了 btrfs root因此先要 umount_all # 再次运行时,有可能 mount 了 btrfs root因此先要 umount_all
# 但目前不需要 mount ,因此用不到 # 但目前不需要 mount ,因此用不到
# umount_all $dir # umount_all "$dir"
rm -rf $dir rm -rf "$dir"
mkdir -p $dir mkdir -p "$dir"
} }
mod_initrd_debian_kali() { mod_initrd_debian_kali() {
@ -3087,6 +3179,14 @@ mod_initrd_debian_kali() {
sed -Ei 's,&&( onlink=),||\1,' etc/udhcpc/default.script sed -Ei 's,&&( onlink=),||\1,' etc/udhcpc/default.script
# hack 2 # hack 2
# 强制使用 screen
# shellcheck disable=SC1003,SC2016
{
echo 'if false && : \' | insert_into_file lib/debian-installer.d/S70menu before 'if [ -x "$bterm" ]' -F
echo 'if true || : \' | insert_into_file lib/debian-installer.d/S70menu before 'if [ -x "$screen_bin" -a' -F
}
# hack 3
# 修改 /var/lib/dpkg/info/netcfg.postinst 运行我们的脚本 # 修改 /var/lib/dpkg/info/netcfg.postinst 运行我们的脚本
netcfg() { netcfg() {
#!/bin/sh #!/bin/sh
@ -3098,18 +3198,24 @@ mod_initrd_debian_kali() {
# 运行 trans.sh保存配置 # 运行 trans.sh保存配置
db_progress INFO base-installer/progress/netcfg db_progress INFO base-installer/progress/netcfg
sh /trans.sh # 添加 || exit ,可以在 debian installer 不兼容 /trans.sh 语法时强制报错
# exit 不带参数,返回值为 || 前面命令的返回值
sh /trans.sh || exit
db_progress STEP 1 db_progress STEP 1
db_progress STOP
} }
# 直接覆盖 net-retriever方便调试
# curl -Lo /usr/lib/debian-installer/retriever/net-retriever $confhome/net-retriever
postinst=var/lib/dpkg/info/netcfg.postinst postinst=var/lib/dpkg/info/netcfg.postinst
get_function_content netcfg >$postinst get_function_content netcfg >$postinst
get_ip_conf_cmd | insert_into_file $postinst after ": get_ip_conf_cmd" get_ip_conf_cmd | insert_into_file $postinst after ": get_ip_conf_cmd"
# cat $postinst # cat $postinst
# hack 4
# 修改 udeb 依赖
# 直接覆盖 net-retriever方便调试
# curl -Lo /usr/lib/debian-installer/retriever/net-retriever $confhome/net-retriever
change_priority() { change_priority() {
while IFS= read -r line; do while IFS= read -r line; do
if [[ "$line" = Package:* ]]; then if [[ "$line" = Package:* ]]; then
@ -3193,32 +3299,44 @@ EOF
# 云内核没有 sata 模块,也没有内嵌,有一个 CONFIG_SATA_HOST=ylibata-$(CONFIG_SATA_HOST) += libata-sata.o # 云内核没有 sata 模块,也没有内嵌,有一个 CONFIG_SATA_HOST=ylibata-$(CONFIG_SATA_HOST) += libata-sata.o
# scsi-modules 默认安装(改成可选),包含 nvme.ko(+) 和各种虚拟化驱动(+) # scsi-modules 默认安装(改成可选),包含 nvme.ko(+) 和各种虚拟化驱动(+)
download_and_extract_udeb() { download_and_extract_deb() {
package=$1 local type=$1
extract_dir=$2 local package=$2
local extract_dir=$3
# 获取 udeb 列表 # shellcheck disable=SC2154
udeb_list=$tmp/udeb_list case "$type" in
if ! [ -f $udeb_list ]; then deb)
# shellcheck disable=SC2154 local mirror=$nextos_deb_mirror
curl -L http://$nextos_udeb_mirror/dists/$nextos_codename/main/debian-installer/binary-$basearch_alt/Packages.gz | local url=http://$mirror/dists/$nextos_codename/main/binary-$basearch_alt/Packages.gz
zcat | grep 'Filename:' | awk '{print $2}' >$udeb_list ;;
udeb)
local mirror=$nextos_udeb_mirror
local url=http://$mirror/dists/$nextos_codename/main/debian-installer/binary-$basearch_alt/Packages.gz
;;
esac
# 获取 deb/udeb 列表
deb_list=$tmp/${type}_list
if ! [ -f $deb_list ]; then
curl -L "$url" | zcat | grep 'Filename:' | awk '{print $2}' >$deb_list
fi fi
# 下载 udeb # 下载 deb/udeb
curl -Lo $tmp/tmp.udeb http://$nextos_udeb_mirror/"$(grep -F /${package}_ $udeb_list)" deb_path=$(grep -F "/${package}_" "$deb_list")
curl -Lo $tmp/tmp.deb http://$mirror/"$deb_path"
if false; then if false; then
# 使用 dpkg # 使用 dpkg
# cygwin 没有 dpkg # cygwin 没有 dpkg
install_pkg dpkg install_pkg dpkg
dpkg -x $tmp/tmp.udeb $extract_dir dpkg -x $tmp/tmp.deb $extract_dir
else else
# 使用 ar tar xz # 使用 ar tar xz
# cygwin 需安装 binutils # cygwin 需安装 binutils
# centos7 ar 不支持 --output # centos7 ar 不支持 --output
install_pkg ar tar xz install_pkg ar tar xz
(cd $tmp && ar x $tmp/tmp.udeb) (cd $tmp && ar x $tmp/tmp.deb)
tar xf $tmp/data.tar.xz -C $extract_dir tar xf $tmp/data.tar.xz -C $extract_dir
fi fi
} }
@ -3262,12 +3380,27 @@ EOF
curl -Lo usr/share/keyrings/debian-archive-keyring.gpg https://deb.freexian.com/extended-lts/archive-key.gpg curl -Lo usr/share/keyrings/debian-archive-keyring.gpg https://deb.freexian.com/extended-lts/archive-key.gpg
fi fi
# 提前下载 sshd
# 以便在配置下载源之前就可以启动 sshd
mkdir_clear $tmp/sshd
download_and_extract_deb udeb openssh-server-udeb $tmp/sshd
cp -r $tmp/sshd/* .
# 提前下载 fdisk # 提前下载 fdisk
# 因为 fdisk-udeb 包含 fdisk 和 sfdisk提前下载可减少占用 # 因为 fdisk-udeb 包含 fdisk 和 sfdisk提前下载可减少占用
mkdir_clear $tmp/fdisk mkdir_clear $tmp/fdisk
download_and_extract_udeb fdisk-udeb $tmp/fdisk download_and_extract_deb udeb fdisk-udeb $tmp/fdisk
cp -f $tmp/fdisk/usr/sbin/fdisk usr/sbin/ cp -f $tmp/fdisk/usr/sbin/fdisk usr/sbin/
# 下载 websocketd
# debian 11+ 才有 websocketd
if [ "$distro" = kali ] ||
{ [ "$distro" = debian ] && [ "$releasever" -ge 11 ]; }; then
mkdir_clear $tmp/websocketd
download_and_extract_deb deb websocketd $tmp/websocketd
cp -f $tmp/websocketd/usr/bin/websocketd usr/bin/
fi
# >256M 或者当前系统是 windows # >256M 或者当前系统是 windows
if [ $ram_size -gt 256 ] || is_in_windows; then if [ $ram_size -gt 256 ] || is_in_windows; then
sed -i '/^pata-modules/d' $net_retriever sed -i '/^pata-modules/d' $net_retriever
@ -3298,7 +3431,7 @@ EOF
# 但反查也找不到 curl https://deb.debian.org/debian/dists/bookworm/main/Contents-udeb-amd64.gz | zcat | grep xen # 但反查也找不到 curl https://deb.debian.org/debian/dists/bookworm/main/Contents-udeb-amd64.gz | zcat | grep xen
if [ -n "$extra_drivers" ]; then if [ -n "$extra_drivers" ]; then
mkdir_clear $tmp/scsi mkdir_clear $tmp/scsi
download_and_extract_udeb scsi-modules-$kver-di $tmp/scsi download_and_extract_deb udeb scsi-modules-$kver-di $tmp/scsi
relative_drivers_dir=lib/modules/$kver/kernel/drivers relative_drivers_dir=lib/modules/$kver/kernel/drivers
udeb_drivers_dir=$tmp/scsi/$relative_drivers_dir udeb_drivers_dir=$tmp/scsi/$relative_drivers_dir
@ -3634,6 +3767,11 @@ This script is outdated, please download reinstall.sh again.
remove_useless_initrd_files remove_useless_initrd_files
fi fi
if [ "$hold" = 0 ]; then
info 'hold 0'
read -r -p 'Press Enter to continue...'
fi
# 重建 # 重建
# 注意要用 cpio -H newc 不要用 cpio -c ,不同版本的 -c 作用不一样,很坑 # 注意要用 cpio -H newc 不要用 cpio -c ,不同版本的 -c 作用不一样,很坑
# -c Use the old portable (ASCII) archive format # -c Use the old portable (ASCII) archive format
@ -3661,14 +3799,15 @@ remove_useless_initrd_files() {
for item in *; do for item in *; do
case "$item" in case "$item" in
# 甲骨文 arm 用自定义镜像支持设为 mlx5 vf 网卡,且不是 azure 那样显示两个网卡 # 甲骨文 arm 用自定义镜像支持设为 mlx5 vf 网卡,且不是 azure 那样显示两个网卡
amazon | google | mellanox) ;; # https://debian.pkgs.org/13/debian-main-amd64/linux-image-6.12.43+deb13-cloud-amd64_6.12.43-1_amd64.deb.html
amazon | google | mellanox | realtek | pensando) ;;
intel) intel)
( (
cd "$item" cd "$item"
for sub_item in *; do for sub_item in *; do
case "$sub_item" in case "$sub_item" in
# 有 e100.ko e1000文件夹 e1000e文件夹 # 有 e100.ko e1000文件夹 e1000e文件夹
e100* | lib* | *vf) ;; e100* | lib* | *vf | idpf) ;;
*) rm -rf $sub_item ;; *) rm -rf $sub_item ;;
esac esac
done done
@ -3722,6 +3861,7 @@ get_unix_path() {
} }
# 脚本入口 # 脚本入口
if mount | grep -q 'tmpfs on / type tmpfs'; then if mount | grep -q 'tmpfs on / type tmpfs'; then
error_and_exit "Can't run this script in Live OS." error_and_exit "Can't run this script in Live OS."
fi fi
@ -3781,17 +3921,22 @@ for o in ci installer debug minimal allow-ping force-cn help \
allow-ping: \ allow-ping: \
commit: \ commit: \
frpc-conf: frpc-config: frpc-toml: \ frpc-conf: frpc-config: frpc-toml: \
force: \ force-boot-mode: \
force-old-windows-setup:; do force-old-windows-setup:; do
[ -n "$long_opts" ] && long_opts+=, [ -n "$long_opts" ] && long_opts+=,
long_opts+=$o long_opts+=$o
done done
# 整理参数 # 整理参数
if ! opts=$(getopt -n $0 -o "h" --long "$long_opts" -- "$@"); then if ! opts=$(getopt -n $0 -o "h,x" --long "$long_opts" -- "$@"); then
exit exit
fi fi
# /tmp 挂载在内存的话,可能不够空间
# 处理 --frpc--toml 时会下载文件,因此在处理参数前就创建临时目录
tmp=/reinstall-tmp
mkdir_clear "$tmp"
eval set -- "$opts" eval set -- "$opts"
# shellcheck disable=SC2034 # shellcheck disable=SC2034
while true; do while true; do
@ -3803,7 +3948,7 @@ while true; do
commit=$2 commit=$2
shift 2 shift 2
;; ;;
--debug) -x | --debug)
set -x set -x
shift shift
;; ;;
@ -3831,7 +3976,7 @@ while true; do
shift shift
;; ;;
--hold | --sleep) --hold | --sleep)
if ! { [ "$2" = 1 ] || [ "$2" = 2 ]; }; then if ! { [ "$2" = 0 ] || [ "$2" = 1 ] || [ "$2" = 2 ]; }; then
error_and_exit "Invalid $1 value: $2" error_and_exit "Invalid $1 value: $2"
fi fi
hold=$2 hold=$2
@ -3840,27 +3985,32 @@ while true; do
--frpc-conf | --frpc-config | --frpc-toml) --frpc-conf | --frpc-config | --frpc-toml)
[ -n "$2" ] || error_and_exit "Need value for $1" [ -n "$2" ] || error_and_exit "Need value for $1"
# windows 路径转换 case "$(to_lower <<<"$2")" in
frpc_config=$(get_unix_path "$2") http://* | https://*)
frpc_config_url=$2
# alpine busybox 不支持 readlink -m frpc_config=$tmp/frpc_config
# readlink -m /asfsafasfsaf/fasf if ! curl -L "$frpc_config_url" -o "$frpc_config"; then
# 因此需要先判断路径是否存在 error_and_exit "Can't get frpc config from $frpc_config_url"
fi
if ! [ -f "$frpc_config" ]; then ;;
error_and_exit "Not a toml file: $2" *)
fi # windows 路径转换
if ! { frpc_config=$(get_unix_path "$2") && [ -f "$frpc_config" ]; }; then
error_and_exit "File not exists: $2"
fi
;;
esac
# 转为绝对路径 # 转为绝对路径
frpc_config=$(readlink -f "$frpc_config") frpc_config=$(readlink -f "$frpc_config")
shift 2 shift 2
;; ;;
--force) --force-boot-mode)
if ! { [ "$2" = bios ] || [ "$2" = efi ]; }; then if ! { [ "$2" = bios ] || [ "$2" = efi ]; }; then
error_and_exit "Invalid $1 value: $2" error_and_exit "Invalid $1 value: $2"
fi fi
force=$2 force_boot_mode=$2
shift 2 shift 2
;; ;;
--passwd | --password) --passwd | --password)
@ -3888,7 +4038,7 @@ EOF
# https://manpages.debian.org/testing/openssh-server/authorized_keys.5.en.html#AUTHORIZED_KEYS_FILE_FORMAT # https://manpages.debian.org/testing/openssh-server/authorized_keys.5.en.html#AUTHORIZED_KEYS_FILE_FORMAT
is_valid_ssh_key() { is_valid_ssh_key() {
grep -qE '^(ecdsa-sha2-nistp(256|384|512)|ssh-(ed25519|rsa)) ' <<<"$1" grep -qE '^(ecdsa-sha2-nistp(256|384|521)|ssh-(ed25519|rsa)) ' <<<"$1"
} }
[ -n "$2" ] || ssh_key_error_and_exit "Need value for $1" [ -n "$2" ] || ssh_key_error_and_exit "Need value for $1"
@ -4041,13 +4191,7 @@ fi
# 密码 # 密码
if ! is_netboot_xyz && [ -z "$ssh_keys" ] && [ -z "$password" ]; then if ! is_netboot_xyz && [ -z "$ssh_keys" ] && [ -z "$password" ]; then
if is_use_dd; then if is_use_dd; then
echo " show_dd_password_tips
This password is only used for SSH access to view logs during the installation.
Password of the image will NOT modify.
密码仅用于安装过程中通过 SSH 查看日志。
镜像的密码不会被修改。
"
fi fi
prompt_password prompt_password
fi fi
@ -4055,10 +4199,6 @@ fi
# 必备组件 # 必备组件
install_pkg curl grep install_pkg curl grep
# /tmp 挂载在内存的话,可能不够空间
tmp=/reinstall-tmp
mkdir_clear "$tmp"
# 强制忽略/强制添加 --ci 参数 # 强制忽略/强制添加 --ci 参数
# debian 不强制忽略 ci 留作测试 # debian 不强制忽略 ci 留作测试
case "$distro" in case "$distro" in
@ -4467,13 +4607,18 @@ EOF
get_function_content load_grubenv_if_not_loaded >$target_cfg get_function_content load_grubenv_if_not_loaded >$target_cfg
# 原系统为 openeuler 云镜像,需要添加 --unrestricted否则要输入密码 # 原系统为 openeuler 云镜像,需要添加 --unrestricted否则要输入密码
del_empty_lines <<EOF | tee -a $target_cfg del_empty_lines <<EOF | del_comment_lines | tee -a $target_cfg
set timeout_style=menu set timeout_style=menu
set timeout=5 set timeout=5
menuentry "$(get_entry_name)" --unrestricted { menuentry "$(get_entry_name)" --unrestricted {
$(! is_in_windows && echo 'insmod lvm') $(! is_in_windows && echo 'insmod lvm')
$(is_os_in_btrfs && echo 'set btrfs_relative_path=n') $(is_os_in_btrfs && echo 'set btrfs_relative_path=n')
# fedora efi 没有 load_video
insmod all_video insmod all_video
# set gfxmode=800x600
# set gfxpayload=keep
# terminal_output gfxterm 在 vultr 上会花屏
# terminal_output console
search --no-floppy --file --set=root $vmlinuz search --no-floppy --file --set=root $vmlinuz
$linux_cmd $vmlinuz $cmdline $linux_cmd $vmlinuz $cmdline
$([ -n "$initrds" ] && echo "$initrd_cmd $initrds") $([ -n "$initrds" ] && echo "$initrd_cmd $initrds")
@ -4492,8 +4637,8 @@ echo "$distro $releasever"
case "$distro" in case "$distro" in
windows) username=administrator ;; windows) username=administrator ;;
dd | netboot.xyz) username= ;; netboot.xyz) username= ;;
*) username=root ;; dd | *) username=root ;;
esac esac
if [ -n "$username" ]; then if [ -n "$username" ]; then
@ -4510,6 +4655,7 @@ if is_netboot_xyz; then
elif is_alpine_live; then elif is_alpine_live; then
echo 'Reboot to start Alpine Live OS.' echo 'Reboot to start Alpine Live OS.'
elif is_use_dd; then elif is_use_dd; then
show_dd_password_tips
echo 'Reboot to start DD.' echo 'Reboot to start DD.'
elif [ "$distro" = fnos ]; then elif [ "$distro" = fnos ]; then
echo "Special note for FNOS:" echo "Special note for FNOS:"

659
trans.sh

File diff suppressed because it is too large Load Diff

View File

@ -12,56 +12,90 @@ rem set ipv6_dns2=::2
@echo off @echo off
mode con cp select=437 >nul mode con cp select=437 >nul
setlocal EnableDelayedExpansion
rem 禁用 IPv6 地址标识符的随机化,防止 IPv6 和后台面板不一致 rem 禁用 IPv6 地址标识符的随机化,防止 IPv6 和后台面板不一致
netsh interface ipv6 set global randomizeidentifiers=disabled netsh interface ipv6 set global randomizeidentifiers=disabled
rem 检查是否定义了 MAC 地址 rem 检查是否定义了 MAC 地址
if defined mac_addr ( if not defined mac_addr goto :del
for /f %%a in ('wmic nic where "MACAddress='%mac_addr%'" get InterfaceIndex ^| findstr [0-9]') do set id=%%a
if defined id (
rem 配置静态 IPv4 地址和网关
if defined ipv4_addr if defined ipv4_gateway (
rem gwmetric 默认值为 1自动跃点需设为 0
netsh interface ipv4 set address !id! static !ipv4_addr! gateway=!ipv4_gateway! gwmetric=0
)
rem 配置静态 IPv4 DNS 服务器 rem vista 没有自带 powershell
for %%i in (1, 2) do ( rem win11 24h2 安装后有 wmic但是过一段时间会自动删除因此有的 dd 镜像没有 wmic
if defined ipv4_dns%%i ( if exist "%windir%\system32\wbem\wmic.exe" (
netsh interface ipv4 add | findstr "dnsservers" rem wmic 换行符是 \r\r\n
if ErrorLevel 1 ( rem 虽然这里用了 findstr 全字匹配 ,但是结尾还是有 \r
rem vista for /f "tokens=2 delims==" %%a in (
netsh interface ipv4 add dnsserver !id! !ipv4_dns%%i! %%i 'wmic nic where "MACAddress='%mac_addr%'" get InterfaceIndex /format:list ^| findstr "^InterfaceIndex=[0-9][0-9]*$"'
) else ( ) do set id=%%a
rem win7 )
netsh interface ipv4 add dnsservers !id! !ipv4_dns%%i! %%i no
) if not defined id (
for /f %%a in ('powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass ^
-Command "(Get-WmiObject Win32_NetworkAdapter | Where-Object { $_.MACAddress -eq '%mac_addr%' }).InterfaceIndex" ^| findstr "^[0-9][0-9]*$"'
) do set id=%%a
)
if not defined id (
for /f %%a in ('powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass ^
-Command "(Get-CimInstance Win32_NetworkAdapter | Where-Object { $_.MACAddress -eq '%mac_addr%' }).InterfaceIndex" ^| findstr "^[0-9][0-9]*$"'
) do set id=%%a
)
if defined id (
rem 配置静态 IPv4 地址和网关
if defined ipv4_addr if defined ipv4_gateway (
rem 如果使用了 setlocal EnableDelayedExpansion
rem netsh interface ipv4 set address !id! static %ipv4_addr% gateway=%ipv4_gateway% gwmetric=0
rem !id! 变量最后有 \r 会导致语句不正确
rem %id% 变量则没有这个问题
rem gwmetric 默认值为 1自动跃点需设为 0
netsh interface ipv4 set address %id% static %ipv4_addr% gateway=%ipv4_gateway% gwmetric=0
)
rem 配置静态 IPv4 DNS 服务器
for %%i in (1, 2) do (
if defined ipv4_dns%%i (
netsh interface ipv4 add | findstr "dnsservers" >nul
if ErrorLevel 1 (
rem vista
setlocal EnableDelayedExpansion
netsh interface ipv4 add dnsserver %id% !ipv4_dns%%i! %%i
endlocal
) else (
rem win7
setlocal EnableDelayedExpansion
netsh interface ipv4 add dnsservers %id% !ipv4_dns%%i! %%i no
endlocal
) )
) )
)
rem 配置 IPv6 地址和网关 rem 配置 IPv6 地址和网关
if defined ipv6_addr if defined ipv6_gateway ( if defined ipv6_addr if defined ipv6_gateway (
netsh interface ipv6 set address !id! !ipv6_addr! netsh interface ipv6 set address %id% %ipv6_addr%
netsh interface ipv6 add route prefix=::/0 !id! !ipv6_gateway! netsh interface ipv6 add route prefix=::/0 %id% %ipv6_gateway%
) )
rem 配置 IPv6 DNS 服务器 rem 配置 IPv6 DNS 服务器
for %%i in (1, 2) do ( for %%i in (1, 2) do (
if defined ipv6_dns%%i ( if defined ipv6_dns%%i (
netsh interface ipv6 add | findstr "dnsservers" netsh interface ipv6 add | findstr "dnsservers" >nul
if ErrorLevel 1 ( if ErrorLevel 1 (
rem vista rem vista
netsh interface ipv6 add dnsserver !id! !ipv6_dns%%i! %%i setlocal EnableDelayedExpansion
) else ( netsh interface ipv6 add dnsserver %id% !ipv6_dns%%i! %%i
rem win7 endlocal
netsh interface ipv6 add dnsservers !id! !ipv6_dns%%i! %%i no ) else (
) rem win7
setlocal EnableDelayedExpansion
netsh interface ipv6 add dnsservers %id% !ipv6_dns%%i! %%i no
endlocal
) )
) )
) )
) )
:del
rem 删除此脚本 rem 删除此脚本
del "%~f0" del "%~f0"