Automontaje de USB, suspender con batería agotada, bloqueo por inactividad y TLP
- automontaje (servicio de runit, root): monta memorias USB y tarjetas SD en /mnt/ETIQUETA o /mnt/sdXY y las desmonta al sacarlas, con notificación. FAT/exFAT/NTFS (ntfs3 del kernel) a nombre del usuario; los discos internos (ID_BUS distinto de usb) no se tocan. - bateria: al 3 % sin cargador avisa y, si en 10 s sigue descargando, suspende con sudo -n zzz (sudoers.d/zzz: solo zzz sin argumentos, sin contraseña, para wheel). - .xinitrc: xss-lock bloquea con slock tras 30 min de inactividad y la pantalla se apaga un minuto después. - install.sh: xss-lock, tlp y tlp-rdw; servicios tlp y automontaje; los sudoers se validan con visudo y se instalan con modo 440. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016UdJsHrbkmzhoCb6TthP2m
This commit is contained in:
parent
2c2adaaa79
commit
2850a4fc73
7 changed files with 148 additions and 10 deletions
3
sistema/etc/sudoers.d/zzz
Normal file
3
sistema/etc/sudoers.d/zzz
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# El script bateria suspende con "sudo -n zzz" cuando la batería llega al
|
||||
# límite. Solo zzz sin argumentos, sin contraseña, para los de wheel.
|
||||
%wheel ALL=(root) NOPASSWD: /usr/bin/zzz ""
|
||||
3
sistema/etc/sv/automontaje/run
Executable file
3
sistema/etc/sv/automontaje/run
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
exec 2>&1
|
||||
exec /usr/local/bin/automontaje
|
||||
98
sistema/usr/local/bin/automontaje
Executable file
98
sistema/usr/local/bin/automontaje
Executable file
|
|
@ -0,0 +1,98 @@
|
|||
#!/bin/sh
|
||||
# Monta solas las memorias USB y tarjetas SD en /mnt/ETIQUETA (o /mnt/sdXY
|
||||
# si no tienen etiqueta) y las desmonta al sacarlas, avisando con una
|
||||
# notificación al usuario de la sesión gráfica. Lo lanza runit como root
|
||||
# (servicio automontaje). Los discos internos no se tocan.
|
||||
|
||||
# Usuario dueño de la sesión de dwm, o el primero normal (UID 1000).
|
||||
usuario() {
|
||||
pid=$(pgrep -xo dwm) && stat -c %u "/proc/$pid" || echo 1000
|
||||
}
|
||||
|
||||
# avisar TÍTULO TEXTO: notificación en la sesión gráfica, si la hay
|
||||
avisar() {
|
||||
pid=$(pgrep -xo dwm) || return 0
|
||||
nombre=$(getent passwd "$(stat -c %u "/proc/$pid")" | cut -d: -f1)
|
||||
entorno=$(tr '\0' '\n' <"/proc/$pid/environ" |
|
||||
grep -E '^(DISPLAY|DBUS_SESSION_BUS_ADDRESS|XDG_RUNTIME_DIR)=')
|
||||
# shellcheck disable=SC2086
|
||||
env $entorno chpst -u "$nombre" notify-send -i drive-removable-media \
|
||||
"$1" "$2" >/dev/null 2>&1 &
|
||||
}
|
||||
|
||||
montar() {
|
||||
dev=$1 tipo=$2 etiqueta=$3
|
||||
findmnt -rn -S "$dev" >/dev/null && return
|
||||
|
||||
dir=/mnt/$(printf %s "$etiqueta" | tr -c 'A-Za-z0-9._-' _)
|
||||
if [ "$dir" = /mnt/ ] || mountpoint -q "$dir" ||
|
||||
{ [ -d "$dir" ] && [ -n "$(ls -A "$dir")" ]; }; then
|
||||
dir=/mnt/${dev#/dev/}
|
||||
fi
|
||||
|
||||
# Los sistemas de archivos de Windows no guardan dueños: se montan a
|
||||
# nombre del usuario para que pueda escribir sin sudo.
|
||||
uid=$(usuario)
|
||||
gid=$(getent passwd "$uid" | cut -d: -f4)
|
||||
opts=nosuid,nodev,noatime
|
||||
case $tipo in
|
||||
vfat) opts=$opts,uid=$uid,gid=$gid,umask=022,utf8,flush ;;
|
||||
exfat) opts=$opts,uid=$uid,gid=$gid,umask=022 ;;
|
||||
ntfs) tipo=ntfs3 opts=$opts,uid=$uid,gid=$gid,umask=022 ;;
|
||||
esac
|
||||
|
||||
mkdir -p "$dir"
|
||||
if mount -t "$tipo" -o "$opts" "$dev" "$dir"; then
|
||||
avisar "Memoria montada" "$dir"
|
||||
else
|
||||
rmdir "$dir" 2>/dev/null
|
||||
avisar "No se pudo montar" "$dev ($tipo)"
|
||||
fi
|
||||
}
|
||||
|
||||
desmontar() {
|
||||
dir=$(findmnt -rn -o TARGET -S "$1") || return 0
|
||||
case $dir in /mnt/*) ;; *) return ;; esac
|
||||
umount -l "$dir" && rmdir "$dir" 2>/dev/null
|
||||
avisar "Memoria desconectada" "$dir"
|
||||
}
|
||||
|
||||
limpiar() {
|
||||
accion='' dev='' bus='' uso='' tipo='' etiqueta=''
|
||||
}
|
||||
|
||||
# Lee eventos de udev (bloques KEY=VALOR separados por una línea vacía).
|
||||
procesar() {
|
||||
limpiar
|
||||
while IFS= read -r linea; do
|
||||
case $linea in
|
||||
ACTION=*) accion=${linea#*=} ;;
|
||||
DEVNAME=*) dev=${linea#*=} ;;
|
||||
ID_BUS=*) bus=${linea#*=} ;;
|
||||
ID_FS_USAGE=*) uso=${linea#*=} ;;
|
||||
ID_FS_TYPE=*) tipo=${linea#*=} ;;
|
||||
ID_FS_LABEL=*) etiqueta=${linea#*=} ;;
|
||||
'')
|
||||
case $bus:$dev in usb:* | *:/dev/mmcblk*) ;; *) dev='' ;; esac
|
||||
if [ -n "$dev" ]; then
|
||||
case $accion in
|
||||
add | change) [ "$uso" = filesystem ] &&
|
||||
montar "$dev" "$tipo" "$etiqueta" ;;
|
||||
remove) desmontar "$dev" ;;
|
||||
esac
|
||||
fi
|
||||
limpiar
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
{
|
||||
# Primero lo que ya está conectado, luego los eventos nuevos
|
||||
for d in /sys/class/block/*; do
|
||||
echo ACTION=add
|
||||
udevadm info --query=property --path="$d"
|
||||
echo
|
||||
done
|
||||
exec udevadm monitor --udev --property --subsystem-match=block
|
||||
} | procesar
|
||||
Loading…
Add table
Add a link
Reference in a new issue