impove luks script

This commit is contained in:
2026-02-15 18:46:05 +01:00
parent 818054f1ab
commit ded9f4e809
3 changed files with 137 additions and 54 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
screenshot-path "~/Pictures/Screenshots/niri_screenshot_%Y-%m-%d_%H-%M-%S.png" screenshot-path "~/Pictures/Screenshots/niri_screenshot_%Y-%m-%d_%H-%M-%S.png"
debug { debug {
render-drm-device "/dev/dri/renderD128" render-drm-device "/dev/dri/renderD129"
} }
// gestures { // gestures {
+119 -33
View File
@@ -7,17 +7,107 @@
# - LUKS_PARTITION: Path to the LUKS partition (overrides auto-detection). # - LUKS_PARTITION: Path to the LUKS partition (overrides auto-detection).
# - LUKS_MAPPER_NAME: Name for the LUKS mapper (default: luks_mount_<timestamp>). # - LUKS_MAPPER_NAME: Name for the LUKS mapper (default: luks_mount_<timestamp>).
# - LUKS_MOUNT_POINT: Mount point for the decrypted volume (default: /mnt/luks). # - LUKS_MOUNT_POINT: Mount point for the decrypted volume (default: /mnt/luks).
# - LUKS_NESTED_UUID: UUID of a device containing a LUKS image file (overrides normal selection).
# - LUKS_NESTED_PATH: Relative path to the LUKS image file inside the partition defined by LUKS_NESTED_UUID.
# - LUKS_SHELL: Shell to use inside the mounted directory (defaults to $SHELL).
# - LUKS_SHELL_COMMAND: Optional command to run instead of an interactive shell (e.g. "ls -la" or "htop").
# - LUKS_KEYFILE: Optional path to a keyfile for unlocking the LUKS volume (instead of password prompt).
# - Cleans up on exit (unmounts and closes the LUKS volume). # - Cleans up on exit (unmounts and closes the LUKS volume).
# Requirements: # Requirements:
# - cryptsetup # - cryptsetup
# - sudo privileges # - sudo privileges
# - fzf (optional, for selecting among multiple LUKS devices) # - fzf (optional, for selecting among multiple LUKS devices)
# - util-linux (findmnt, lsblk)
set -euo pipefail set -euo pipefail
[ "$(id -u)" -eq 0 ] && { # [ "$(id -u)" -eq 0 ] && {
echo "[ERROR] Do not run this script in sudo mode." >&2 # echo "[ERROR] Do not run this script in sudo mode." >&2
# exit 1
# }
LUKS_PARTITION="${LUKS_PARTITION:-}"
# Default to a unique name based on timestamp
LUKS_MAPPER_NAME="${LUKS_MAPPER_NAME:-luks_mount_$(date +%s)}"
# Fixed default mount point though
LUKS_MOUNT_POINT="${LUKS_MOUNT_POINT:-/mnt/luks}"
LUKS_NESTED_UUID="${LUKS_NESTED_UUID:-}"
LUKS_NESTED_PATH="${LUKS_NESTED_PATH:-}"
LUKS_SHELL="${LUKS_SHELL:-${SHELL:-/bin/bash}}"
LUKS_SHELL_COMMAND="${LUKS_SHELL_COMMAND:-}"
LUKS_KEYFILE="${LUKS_KEYFILE:-}"
# Flag to track if we created the mount point directory
mountpoint_created=0
# --- Cleanup Logic ---
cleanup() {
echo "[INFO] Cleaning up..." >&2
# Make sure we are not in the mount point when unmounting
popd &>/dev/null || cd "$HOME" || cd / || true
if mountpoint -q "$LUKS_MOUNT_POINT"; then
echo "[INFO] Unmounting LUKS volume..." >&2
sudo umount "$LUKS_MOUNT_POINT" || echo "[WARNING] Failed to unmount." >&2
fi
if [ -e "/dev/mapper/$LUKS_MAPPER_NAME" ]; then
echo "[INFO] Closing LUKS mapper..." >&2
sudo cryptsetup close "$LUKS_MAPPER_NAME" || echo "[WARNING] Failed to close LUKS mapper." >&2
fi
if [ $mountpoint_created -eq 1 ] && [ -d "$LUKS_MOUNT_POINT" ]; then
echo "[INFO] Removing mount point..." >&2
sudo rmdir "$LUKS_MOUNT_POINT" || echo "[WARNING] Failed to remove mount point." >&2
fi
# Cleanup Outer Partition if it exists
if [ -n "$OUTER_MOUNT_POINT" ]; then
if mountpoint -q "$OUTER_MOUNT_POINT"; then
echo "[INFO] Unmounting outer partition..." >&2
sudo umount "$OUTER_MOUNT_POINT" || echo "[WARNING] Failed to unmount outer partition." >&2
fi
if [ -d "$OUTER_MOUNT_POINT" ]; then
echo "[INFO] Removing outer mount point..." >&2
rmdir "$OUTER_MOUNT_POINT" || echo "[WARNING] Failed to remove outer mount point." >&2
fi
fi
echo "[INFO] Done." >&2
}
trap cleanup EXIT INT TERM
# --- Nested Partition Logic ---
OUTER_MOUNT_POINT=""
handle_nested_partition() {
local uuid="$1"
local NESTED_path="$2"
# Find the device node for the given UUID
local outer_device
outer_device=$(lsblk -nplo NAME,UUID | awk -v uuid="$uuid" '$2 == uuid {print $1}')
if [ -z "$outer_device" ]; then
echo "[ERROR] Could not find device with UUID=$uuid" >&2
exit 1 exit 1
fi
echo "[INFO] Found outer device: $outer_device" >&2
# Create a temporary mount point for the outer partition
OUTER_MOUNT_POINT=$(mktemp -d -t luks_outer_XXXXXX)
echo "[INFO] Mounting outer device to $OUTER_MOUNT_POINT..." >&2
if ! sudo mount "$outer_device" "$OUTER_MOUNT_POINT"; then
echo "[ERROR] Failed to mount outer device." >&2
rmdir "$OUTER_MOUNT_POINT"
exit 1
fi
local luks_image="$OUTER_MOUNT_POINT/$NESTED_path"
if [ ! -f "$luks_image" ]; then
echo "[ERROR] LUKS image not found at: $luks_image" >&2
sudo umount "$OUTER_MOUNT_POINT"
rmdir "$OUTER_MOUNT_POINT"
exit 1
fi
LUKS_PARTITION="$luks_image"
} }
find_luks_device() { find_luks_device() {
@@ -43,58 +133,54 @@ find_luks_device() {
fi fi
} }
LUKS_PARTITION="${LUKS_PARTITION:-$(find_luks_device)}" if [ -n "$LUKS_NESTED_UUID" ]; then
[ -z "$LUKS_PARTITION" ] && exit 1 if [ -z "$LUKS_NESTED_PATH" ]; then
echo "[ERROR] LUKS_NESTED_PATH must be set when using LUKS_NESTED_UUID." >&2
exit 1
fi
handle_nested_partition "$LUKS_NESTED_UUID" "$LUKS_NESTED_PATH"
elif [ -z "$LUKS_PARTITION" ]; then
LUKS_PARTITION=$(find_luks_device)
fi
# Default to a unique name based on timestamp [ -z "$LUKS_PARTITION" ] && exit 1
LUKS_MAPPER_NAME="${LUKS_MAPPER_NAME:-luks_mount_$(date +%s)}"
# Fixed default mount point though
LUKS_MOUNT_POINT="${LUKS_MOUNT_POINT:-/mnt/luks}"
echo "[INFO] Partition: $LUKS_PARTITION" >&2 echo "[INFO] Partition: $LUKS_PARTITION" >&2
echo "[INFO] Mapper: $LUKS_MAPPER_NAME" >&2 echo "[INFO] Mapper: $LUKS_MAPPER_NAME" >&2
echo "[INFO] Mount: $LUKS_MOUNT_POINT" >&2 echo "[INFO] Mount: $LUKS_MOUNT_POINT" >&2
mount_point_created=0
if [ ! -d "$LUKS_MOUNT_POINT" ]; then if [ ! -d "$LUKS_MOUNT_POINT" ]; then
sudo mkdir -p "$LUKS_MOUNT_POINT" sudo mkdir -p "$LUKS_MOUNT_POINT"
mount_point_created=1 mountpoint_created=1
fi fi
if ! sudo cryptsetup open "$LUKS_PARTITION" "$LUKS_MAPPER_NAME"; then CRYPT_ARGS=()
if [ -n "$LUKS_KEYFILE" ]; then
if [ ! -f "$LUKS_KEYFILE" ]; then
echo "[ERROR] Key file not found: $LUKS_KEYFILE" >&2
exit 1
fi
CRYPT_ARGS+=(--key-file "$LUKS_KEYFILE")
fi
if ! sudo cryptsetup open "${CRYPT_ARGS[@]}" "$LUKS_PARTITION" "$LUKS_MAPPER_NAME"; then
echo "[ERROR] Failed to open device." >&2 echo "[ERROR] Failed to open device." >&2
exit 1 exit 1
fi fi
cleanup() {
echo "[INFO] Cleaning up..." >&2
# Make sure we are not in the mount point when unmounting
cd "$HOME" || true
if mountpoint -q "$LUKS_MOUNT_POINT"; then
sudo umount "$LUKS_MOUNT_POINT" || echo "[WARNING] Failed to unmount." >&2
fi
if [ -e "/dev/mapper/$LUKS_MAPPER_NAME" ]; then
sudo cryptsetup close "$LUKS_MAPPER_NAME" || echo "[WARNING] Failed to close LUKS mapper." >&2
fi
if [ $mount_point_created -eq 1 ] && [ -d "$LUKS_MOUNT_POINT" ]; then
sudo rmdir "$LUKS_MOUNT_POINT" || echo "[WARNING] Failed to remove mount point." >&2
fi
echo "[INFO] Done." >&2
}
trap cleanup EXIT INT TERM
sudo mount "/dev/mapper/$LUKS_MAPPER_NAME" "$LUKS_MOUNT_POINT" sudo mount "/dev/mapper/$LUKS_MAPPER_NAME" "$LUKS_MOUNT_POINT"
echo "[INFO] Successfully mounted at $LUKS_MOUNT_POINT." >&2 echo "[INFO] Successfully mounted at $LUKS_MOUNT_POINT." >&2
echo "[INFO] Exit this shell to unmount and close the LUKS volume." >&2 echo "[INFO] Exit this shell to unmount and close the LUKS volume." >&2
cd "$LUKS_MOUNT_POINT" pushd "$LUKS_MOUNT_POINT" &>/dev/null
USER_SHELL="${SHELL:-/bin/bash}" if [[ -n "$LUKS_SHELL_COMMAND" ]]; then
if [[ "$USER_SHELL" == *"/bash" ]]; then eval "$LUKS_SHELL_COMMAND"
"$USER_SHELL" --rcfile <( elif [[ "$LUKS_SHELL" == *"/bash" ]]; then
"$LUKS_SHELL" --rcfile <(
cat ~/.bashrc 2>/dev/null cat ~/.bashrc 2>/dev/null
printf '%s\n' 'PS1="\[\e[1;31m\][LUKS]\[\e[0m\][\u@\h \W]\$ "' printf '%s\n' 'PS1="\[\e[1;31m\][LUKS]\[\e[0m\][\u@\h \W]\$ "'
) -i ) -i
else else
"$USER_SHELL" "$LUKS_SHELL"
fi fi
+15 -18
View File
@@ -24,9 +24,8 @@
- [快速检测](#快速检测) - [快速检测](#快速检测)
- [显示效果](#显示效果) - [显示效果](#显示效果)
- [性能测试](#性能测试) - [性能测试](#性能测试)
- [KGP Unicode Placeholders](#kgp-unicode-placeholders) - [Kitty 图像协议](#kitty-图像协议)
- [特性](#特性) - [Unicode Placeholders](#unicode-placeholders)
- [使用](#使用)
- [实现](#实现) - [实现](#实现)
- [默认 Shell](#默认-shell) - [默认 Shell](#默认-shell)
- [一些概念](#一些概念) - [一些概念](#一些概念)
@@ -469,9 +468,9 @@ KGP 既支持直接传输 PNG 二进制数据, 也支持传输 24bit 与 32bit
是的, 限制宽度并不会减少控制序列的大小, 反而会因为 `,width=100` 元数据增加 10 字节. 是的, 限制宽度并不会减少控制序列的大小, 反而会因为 `,width=100` 元数据增加 10 字节.
### KGP Unicode Placeholders ### Kitty 图像协议
#### 特性 #### Unicode Placeholders
Unicode Placeholders 是 Kitty 图像协议中处理如何放置图像的方法之一, 它允许使用占位符嵌入图像, 这提供了一些有意思的特性: Unicode Placeholders 是 Kitty 图像协议中处理如何放置图像的方法之一, 它允许使用占位符嵌入图像, 这提供了一些有意思的特性:
@@ -487,15 +486,13 @@ Unicode Placeholders 是 Kitty 图像协议中处理如何放置图像的方法
需要注意的是, Unicode Placeholders 仅仅是 KGP 所涉及的一种放置方法, 并不是一种全新的协议或控制序列. 因此, 只有支持 KGP 的终端模拟器才可能支持 Unicode Placeholders, 但反过来说, 支持 KGP 的终端模拟器不一定支持 Unicode Placeholders. 需要注意的是, Unicode Placeholders 仅仅是 KGP 所涉及的一种放置方法, 并不是一种全新的协议或控制序列. 因此, 只有支持 KGP 的终端模拟器才可能支持 Unicode Placeholders, 但反过来说, 支持 KGP 的终端模拟器不一定支持 Unicode Placeholders.
#### 使用
该特性可通过 `kitty +kitten icat` 的 `--unicode-placeholders` 参数启用. 该特性可通过 `kitty +kitten icat` 的 `--unicode-placeholders` 参数启用.
虽然这个特性很有趣, 但就目前而言真正实现它的终端模拟器寥寥无几, 在[前面的表格](#各终端支持情况)中只有 Kitty 和 Ghostty 位于此列, 其他终端模拟器即便支持 KGP, 也只会同时显示占位符和正常的图片, 效果非常诡异. 虽然这个特性很有趣, 但就目前而言真正实现它的终端模拟器寥寥无几, 在[前面的表格](#各终端支持情况)中只有 Kitty 和 Ghostty 位于此列, 其他终端模拟器即便支持 KGP, 也只会同时显示占位符和正常的图片, 效果非常诡异.
#### 实现 #### 实现
指编码端的实现. 如前文所说, Unicode Placeholders 是 KGP 的一个子功能, 因此实现 Unicode Placeholders 的同时也可以(或者说必须)实现 KGP 的基础部分. 以下摘取[前面](#性能测试)提到的 idog 的部分实现思路. 完整实现可见 [Uyanide/idog](https://github.com/Uyanide/idog). 指编码端的实现. 如前文所说, Unicode Placeholders 是 KGP 的一个子功能, 因此 KGP 的基础部分后也可以~~(顺便)~~实现 Unicode Placeholders. 以下摘取[前面](#性能测试)提到的 idog 的部分实现思路. 完整实现可见 [Uyanide/idog](https://github.com/Uyanide/idog).
- 构造 KGP 检测序列 - 构造 KGP 检测序列
可以大致分为四个部分: 可以大致分为四个部分:
@@ -505,7 +502,7 @@ Unicode Placeholders 是 Kitty 图像协议中处理如何放置图像的方法
- `t`: 通过临时文件传输像素数据, 传输完成后临时文件**会被终端模拟器删除**. - `t`: 通过临时文件传输像素数据, 传输完成后临时文件**会被终端模拟器删除**.
- `f`: 通过文件传输像素数据, 传输完成后不会删除. - `f`: 通过文件传输像素数据, 传输完成后不会删除.
- 检测是否支持特定图片数据格式 - 检测是否支持特定数据格式
- `24`: 24bit RGB 原始像素数据 - `24`: 24bit RGB 原始像素数据
- `32`: 32bit RGBA 原始像素数据 - `32`: 32bit RGBA 原始像素数据
- `100`: PNG 二进制数据 - `100`: PNG 二进制数据
@@ -533,15 +530,15 @@ Unicode Placeholders 是 Kitty 图像协议中处理如何放置图像的方法
- `payload` 包含了图片数据, 格式取决于 `t` 和 `f` 选项的值: - `payload` 包含了图片数据, 格式取决于 `t` 和 `f` 选项的值:
| Medium (`t`) | Format (`f`) | Payload | | Medium (`t`) | Format (`f`) | Payload |
| ------------ | ------------ | --------------------------------------------------- | | ------------ | ------------ | ---------------------------------------------- |
| `d` | `24` / `32` | 经过 Base64 编码和可选的 zlib 压缩的像素数据 | | `d` | `24` / `32` | Base64 编码和可选的 zlib 压缩的像素数据 |
| `d` | `100` | 经过 Base64 编码和可选的 zlib 压缩的 PNG 二进制数据 | | `d` | `100` | Base64 编码和可选的 zlib 压缩的 PNG 二进制数据 |
| `s` | `24` / `32` | 经过 Base64 编码的共享内存名称, 存储原始像素数据 | | `s` | `24` / `32` | Base64 编码的共享内存名称, 存储原始像素数据 |
| `s` | `100` | 经过 Base64 编码的共享内存名称, 存储 PNG 二进制数据 | | `s` | `100` | Base64 编码的共享内存名称, 存储 PNG 二进制数据 |
| `t` | `24` / `32` | 经过 Base64 编码的临时文件路径, 存储原始像素数据 | | `t` | `24` / `32` | Base64 编码的临时文件路径, 存储原始像素数据 |
| `t` | `100` | 经过 Base64 编码的临时文件路径, 存储 PNG 二进制数据 | | `t` | `100` | Base64 编码的临时文件路径, 存储 PNG 二进制数据 |
| `f` | `24` / `32` | 经过 Base64 编码的文件路径, 存储原始像素数据 | | `f` | `24` / `32` | Base64 编码的文件路径, 存储原始像素数据 |
| `f` | `100` | 经过 Base64 编码的文件路径, 存储 PNG 二进制数据 | | `f` | `100` | Base64 编码的文件路径, 存储 PNG 二进制数据 |
需要注意的是, **共享内存名称**不包含路径, 也不包含前缀的`/`. 例如某共享内存完整路径为 `/dev/shm/idog_12345678`, 则共享内存名称为 `idog_12345678`. 需要注意的是, **共享内存名称**不包含路径, 也不包含前缀的`/`. 例如某共享内存完整路径为 `/dev/shm/idog_12345678`, 则共享内存名称为 `idog_12345678`.