goCryptfs create a auto mount/unmount folder
#!/usr/bin/env bash
set -euo pipefail
VAULT_NAME="${1:-vault}"
if [[ ! "$VAULT_NAME" =~ ^[a-zA-Z0-9._-]+$ ]]; then
echo "错误:保险库名称只能包含字母、数字、点、下划线和连字符" >&2
exit 1
fi
CIPHER_DIR="$HOME/.local/share/${VAULT_NAME}.enc"
MOUNT_DIR="$HOME/$VAULT_NAME"
BIN_DIR="$HOME/.local/bin"
SYSTEMD_DIR="$HOME/.config/systemd/user"
CTL_SCRIPT="$BIN_DIR/gocryptfs-$VAULT_NAME"
SERVICE_NAME="gocryptfs-$VAULT_NAME.service"
SERVICE_FILE="$SYSTEMD_DIR/$SERVICE_NAME"
SECRET_APP="gocryptfs"
SECRET_VAULT="$VAULT_NAME"
require_cmd() {
command -v "$1" >/dev/null 2>&1 || {
echo "错误:未找到命令 $1" >&2
exit 1
}
}
init_directories() {
mkdir -p "$CIPHER_DIR" "$MOUNT_DIR" "$BIN_DIR" "$SYSTEMD_DIR"
chmod 700 "$CIPHER_DIR" "$MOUNT_DIR" "$BIN_DIR"
}
store_password() {
if secret-tool lookup app "$SECRET_APP" vault "$SECRET_VAULT" \
>/dev/null 2>&1; then
echo "secret-tool 中已存在保险库密码"
return
fi
local password confirm
read -r -s -p "请输入 gocryptfs 密码: " password
echo
read -r -s -p "请再次输入密码: " confirm
echo
if [[ -z "$password" ]]; then
echo "错误:密码不能为空" >&2
exit 1
fi
if [[ "$password" != "$confirm" ]]; then
echo "错误:两次输入的密码不一致" >&2
exit 1
fi
printf '%s\n' "$password" |
secret-tool store \
--label="gocryptfs $VAULT_NAME" \
app "$SECRET_APP" \
vault "$SECRET_VAULT"
unset password confirm
}
init_vault() {
if [[ -f "$CIPHER_DIR/gocryptfs.conf" ]]; then
echo "加密目录已经初始化:$CIPHER_DIR"
return
fi
gocryptfs -init \
-extpass "secret-tool lookup app $SECRET_APP vault $SECRET_VAULT" \
"$CIPHER_DIR"
}
install_control_script() {
cat > "$CTL_SCRIPT" <<EOF
#!/usr/bin/env bash
set -euo pipefail
CIPHER_DIR="$CIPHER_DIR"
MOUNT_DIR="$MOUNT_DIR"
SECRET_APP="$SECRET_APP"
SECRET_VAULT="$SECRET_VAULT"
get_password_command() {
printf 'secret-tool lookup app %q vault %q' "\$SECRET_APP" "\$SECRET_VAULT"
}
case "\${1:-mount}" in
mount)
mkdir -p "\$MOUNT_DIR"
if mountpoint -q "\$MOUNT_DIR"; then
echo "已经挂载:\$MOUNT_DIR"
exit 0
fi
exec gocryptfs \
-extpass "\$(get_password_command)" \
"\$CIPHER_DIR" \
"\$MOUNT_DIR"
;;
umount)
if ! mountpoint -q "\$MOUNT_DIR"; then
echo "未挂载:\$MOUNT_DIR"
exit 0
fi
if command -v fusermount3 >/dev/null 2>&1; then
exec fusermount3 -u "\$MOUNT_DIR"
else
exec fusermount -u "\$MOUNT_DIR"
fi
;;
status)
if mountpoint -q "\$MOUNT_DIR"; then
echo "已挂载:\$MOUNT_DIR"
else
echo "未挂载:\$MOUNT_DIR"
fi
;;
*)
echo "用法:\$0 {mount|umount|status}" >&2
exit 1
;;
esac
EOF
chmod 700 "$CTL_SCRIPT"
}
install_systemd_service() {
cat > "$SERVICE_FILE" <<EOF
[Unit]
Description=Auto mount gocryptfs vault: $VAULT_NAME
After=default.target
[Service]
Type=forking
ExecStart=$CTL_SCRIPT mount
ExecStop=$CTL_SCRIPT umount
Restart=no
[Install]
WantedBy=default.target
EOF
chmod 600 "$SERVICE_FILE"
}
enable_service() {
systemctl --user daemon-reload
systemctl --user enable "$SERVICE_NAME"
systemctl --user restart "$SERVICE_NAME" 2>/dev/null ||
systemctl --user start "$SERVICE_NAME"
}
main() {
require_cmd gocryptfs
require_cmd secret-tool
require_cmd mountpoint
require_cmd systemctl
init_directories
store_password
init_vault
install_control_script
install_systemd_service
enable_service
echo
echo "初始化完成"
echo "加密目录:$CIPHER_DIR"
echo "明文目录:$MOUNT_DIR"
echo "服务名称:$SERVICE_NAME"
echo
echo "当前状态:"
"$CTL_SCRIPT" status
}
main "$@"
FUSE file system on user mode

浙公网安备 33010602011771号