Tener un dump de las bases de datos es una buena practica, pero asumamos que de las dos formas, de guardar tus bases, elegiste la mas radical.

Introducción

Un respaldo regular te permite deshacer cambios en caso de que estés trasteando en tus sitios web, con lo que puedes ir probando loo que cause algún problema. Respaldos históricos de mas largo plazo también ayudan en caso de que no sepas cuando ha ocurrido algún cambio perjudicial en tu sitio, pero por el momento, yo ya te sugerí un sistema rápido para hacer respaldos de 7 dias. En ese articulo explicaba que se podía automatizar y toda la cosa, pero el resultado era un enorme archivo de dump, conteniendo todas las bases de datos que hayan en tu servidor en un solo enorme archivo.

El problema

Si bien un archivo único permite tener un punto de restauración general para todas tus web, también significa que es un bulto inmenso que no vas a poder controlar fácilmente. Mis sitios non son muy voluminosos, así que a lo mucho el dump completo solo alcanza los 270MB. No es algo complicado de almacenar ni distribuir, pero si que es una pesadilla para los editores de texto.Al restaurar un volcado de base de datos, el interprete recorre todo el archivo indiscriminadamente, ejecutando todo lo registrado alli. Pero si solo quieres restaurar un solo archivo, probablemente esto sea «gastar pólvora en gallinazos» porque solo quieres restaurar una base de datos. Probablemente la mas pequeña incluso.No intentes abrirlo desde la consola con un editor de texto. Se colgará tu equipo. Tampoco con un editor visual. Puedes arriesgarte con un editor SQL y tendrías mas suerte, pero es muy probable que se ponga lento y sea pesado de trabajar con el. Estarás sufriendo todo el rato e incluso los cambios mas ligeros pueden ser un tormento. Y lo peor es que modificar un dump de SQL puede provocar errores bien raros que te ahorrarías solo restaurando el volcado original. Lo que necesitas es una forma de recuperar solo la base de datos especifica que quieres restaurar.

La solución

Si eres tan noob como yo y llevaste al colapso tu computador intentando infructuosamente editar un mega archivo de texto, te recomiendo en cambio, la magia del AWK.

AWK es un lenguaje de programación y una herramienta de línea de comandos utilizada para procesar archivos de texto. Permite analizar y manipular datos basándose en patrones, procesando los archivos línea por línea y dividiéndolos en campos (columnas). Es muy útil para filtrar, transformar y generar informes a partir de datos estructurados. El nombre proviene de las iniciales de sus creadores: Alfred Aho, Peter Weinberger y Brian Kernighan.

Puedes usar AWK directo desde la consola, pero es mejor que guardes un script que tenga una logica que buscas de forma congruente. Te sugiero para eso, este script que mediante AWK separa un Dump total en diferentes archivos sql de cada una de las bases contenidas, asumiendo como separador «– Current Database».Cuando encuentra una de estas líneas, extrae el nombre de la base de datos (dbname). Abre un nuevo archivo llamado nombre_de_la_bd.sql en el directorio especificado. Todas las líneas siguientes se escriben en ese nuevo archivo hasta que se encuentra la línea de cabecera de la próxima base de datos. Finalmente, tendrás un archivo SQL para cada base de datos en tu directorio de salida.Para ejecutar este código, debes invocarlo de la siguiente manera:./split_mysqldump.sh archivo_dump_maestro.sql directorio_salida🖕Recuerda que el nombre del archivo queda a tu criterio. En mi caso le puse split_mysqldump para sonar genial XD

1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233343536373839404142434445#!/bin/bash# Script revisado para dividir un dump de multiples bases de datos en archivos individuales.# Uso: ./split_mysqldump_v2.sh <archivo_dump_maestro.sql> <directorio_salida>DUMP_FILE=$1OUTPUT_DIR=$2if [ -z "$DUMP_FILE" ] || [ -z "$OUTPUT_DIR" ]; then echo "Uso: $0 <archivo_dump_maestro.sql> <directorio_salida>" exit 1fi# Crear el directorio de salida si no existemkdir -p "$OUTPUT_DIR"echo "Directorio de salida: $OUTPUT_DIR"# Usar awk para procesar el archivo y redirigir a archivos individualesawk -v out_dir="$OUTPUT_DIR" ' /^-- Current Database: `[^`]+`/ { # Extraer el nombre de la base de datos match($0, /`[^`]+`/); dbname = substr($0, RSTART+1, RLENGTH-2); # Construir el nombre del archivo de salida output_file = out_dir "/" dbname ".sql"; # Imprimir mensaje de depuración en stderr (consola) print "-> Iniciando volcado para BD: " dbname " en " output_file > "/dev/stderr"; # Cerrar el archivo anterior si existe (para evitar problemas) if (current_file && current_file != output_file) { close(current_file); } current_file = output_file; } { # Escribir la línea actual en el archivo de la BD actual if (current_file) { print $0 >> current_file; } }' "$DUMP_FILE"echo "Proceso completado. Archivos individuales creados en: $OUTPUT_DIR"

Una vez que hayas conseguido tus archivos, usa tu comando para poder restaurar la base de datos que necesitas.mysql -u [usuario] -p < nombre_de_tu_bd.sql🖕Usa mariadb en lugar de mysql si así tienes instalado.

Explicación

No te recomiendo agarrar y ejecutar códigos encontrados por internet. tampoco el mio, pero te ayudare a entender lo que estas ejecutando al menos, asi, puedes intentar construir uno propio. Pero al menos por experiencia propia, este código me funcionó a mi XD 

awk -v out_dir=OUTPUT_DIR ...1. Inicialización y Variables de Entrada: El comando se ejecuta con awk. La opción -v out_dir=OUTPUT_DIR pasa una variable externa llamada OUTPUT_DIR (que debe ser reemplazada por la ruta real del directorio de salida al ejecutar el comando) a la variable interna de awk out_dir.Current Database2. Patrón de Búsqueda: awk procesa el archivo de entrada línea por línea. Este fragmento de texto (Current Database) actúa como un patrón. Cuando una línea del archivo de entrada coincide con este patrón (es decir, la línea contiene "Current Database"), se ejecutan las acciones dentro del bloque.match($0, /dbname/)3. Extracción del Nombre de la BD: Dentro del bloque de acción, match($0, /dbname/) busca la palabra «dbname» en la línea actual ($0). Esta función es parte del código de ejemplo que describes, aunque la lógica completa para extraer el nombre real de la BD de la línea suele ser más compleja (ej. usando expresiones regulares). Asumiendo que la línea contiene el nombre de la BD, la siguiente parte se encarga de aislarlo.dbname = substr($0, RSTART, RLENGTH)4. Almacenamiento del Nombre: Utiliza la función substr para extraer el nombre real de la base de datos de la línea actual. RSTART y RLENGTH son variables especiales de awk que se establecen automáticamente por la función match y marcan el inicio y la longitud de la coincidencia encontrada.output_file = out_dir "/" dbname ".sql"5. Construcción del Nombre del Archivo: Se construye la ruta completa del archivo de salida combinando el directorio de salida (out_dir), el nombre de la base de datos (dbname) y la extensión .sql.print "Iniciando volcado para BD: " dbname " en " output_file > "/dev/stderr";6. Salida por pantalla: Muestra el resultado del script en la consola mediante el /dev/stderrif (current_file && current_file != output_file) close(current_file)7. Cierre del Archivo Anterior: Si ya se estaba escribiendo en un archivo anterior (current_file existe) y este es diferente al nuevo output_file, se cierra el archivo anterior para evitar problemas de escritura simultánea o corrupción de datos.current_file = output_file8. Actualización del Archivo Actual: La variable current_file se actualiza para apuntar al nuevo archivo de salida que se acaba de determinar.if (current_file) print $0 >> current_file9. Escritura de la Línea: Finalmente, si existe un archivo actual definido, la línea completa que se está procesando ($0) se escribe (con >>, que significa añadir al final o crear si no existe) en el current_file.

Conclusión

Si usas Windows e intentas modificar el archivo dump sin cuidado, te encontraras con errores molestos de caracteres. esto es porque tienes que controlar la codificación de caracteres original y en windows se suele cambiar a la codificación que se usa alli. Puedes utilizar Notepad++ pues te dice la codificación y permite cambiar entre ellas, pero de todas formas puedes desbordar la memoria con un archivo de mas de 10mb, así que lo mejor es utilizar un script que separe las bases de datos o directamente exportar en bases individuales.

https://interlan.ec/2025/11/28/articulo-segmentar-dump-de-mysql/

#articulo #code2 #linux #mariadb #mysql #selfhosting #servidores #solucionDeProblemas #vps

Ya hace rato no publicaba sobre los logs de mi server. No es que falte material, pero lo que sucede parece rutinario ahora.

El Evento y los logs

Esta vez es curioso. Hoy al entrar en mi blog, no noté nada raro. De hecho, parecía estar mas fluido que de costumbre. Pero entré a mi server por SSH y… pos nada. Por pura coincidencia me llamó la atención un viejo Script que no recuerdo de donde lo saqué y que permitía ver la lista de los procesos que mas ocupan y lo ejecuté. PHP suele tener un alto consumo de RAM, pero no de CPU y hoy se marcaba un 23.9% en 3 procesos distintos.

Consumo de Recursos por PHP y Mariadb

Revise el monitor del sistema de mi server y efectivamente había un alto consumo de CPU, así que fui directo a los logs.

Alto consumo de CPU en el servidor

Efectivamente había alguien haciendo travesuras con mi servidor.

IP 34.83.37.113 atacando

Decidí disparar primero y preguntar después así que le mande un bloqueo por IP

fail2ban-client set wordpress banip 34.83.37.113

Y visitar la pagina ipabusedb para consultar que novedades tenia.

IPAbusedb 34.83.37.113

Por cierto, comparto el código. Admito que debí conservar su origen, pero si lo encuentro de nuevo, lo citaré.

1 2 3 4 5 6 7 8 910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061#!/bin/bashexport LC_ALL=C bashtHost="$(hostname)"tTime="$(date +"%d/%m/%Y a las %H:%M:%S")"tMemTotal="$(free -mh | grep "Mem:" | awk '{print $2}')"tMemUsed="$(free -mh | grep "Mem:" | awk '{print $3}')"tMemFree="$(free -mh | grep "Mem:" | awk '{print $4}')"tLoadAverage="$(uptime | rev | cut -d ":" -f 1 | rev | cut -d " " -f 2-10)"columna_CPU=57columnas_total=$(tput cols)# Si la terminal es grande lo ponemos en dos columnas, si no en una solaif [ $columnas_total -gt 99 ] then fila_CPU=5 else fila_CPU=19 columna_CPU=0fitput clear # Borrado pantalla# Mostrar info printf "\n$tHost - $tTime"printf "\nRAM: $tMemUsed usados de $tMemTotal totales ($tMemFree M libres)\nCarga media de la CPU: $tLoadAverage\n"# Mostrar procesos que consumen RAMecho -e "\n[+] Listado de Procesos top10 consumo de RAM:\n"# Encabezadops -A --sort=-rss --format pid,user,pmem,rss,comm | head -n 1# Procesostput setaf 1 # Rojops -A --sort=-rss --format pid,user,pmem,rss,comm | sed -n '2,6p'tput setaf 3 # Amarillops -A --sort=-rss --format pid,user,pmem,rss,comm | sed -n '7,9p'tput setaf 2 # Verdeps -A --sort=-rss --format pid,user,pmem,rss,comm | sed -n '10,11p'tput sgr0 # Volver al color normal# Columna CPUtput cup $fila_CPU $columna_CPU; echo -e "[+] Listado de Procesos top10 consumo CPU:\n"# Encabezadotput cup $(($fila_CPU + 2)) $columna_CPU; ps -A --sort=-pcpu --format pid,user,pcpu,rss,comm | head -n 1# Procesostput setaf 1 # Rojofor (( i=2; i<=6; i++ ))do tput cup $(($i + $fila_CPU + 1)) $columna_CPU; ps -A --sort=-pcpu --format pid,user,pcpu,rss,comm | sed -n "$i,$i p"donetput setaf 3 # Amarillofor (( i=7; i<=9; i++ ))do tput cup $(($i + $fila_CPU + 1)) $columna_CPU; ps -A --sort=-pcpu --format pid,user,pcpu,rss,comm | sed -n "$i,$i p"donetput setaf 2 # Verdefor (( i=10; i<=11; i++ ))do tput cup $(($i + $fila_CPU + 1)) $columna_CPU; ps -A --sort=-pcpu --format pid,user,pcpu,rss,comm | sed -n "$i,$i p"donetput sgr0

Sobre lo sucedido

Claramente es un ataque de fuerza bruta contra xmlrpc.php por parte de esa IP que molestaba. No estoy muy seguro de que quería y al ver que abuseipdb decía que pertenecía a Google, lo obvio era concluir que era culpa de Google, pero le di la oportunidad de defenderse. Esto es lo que responde:

La IP

113.37.83.34.bc.googleusercontent.com no significa que Google te esté atacando directamente, sino que alguien está utilizando los servicios de alojamiento en la nube de Google, como Google Cloud o Compute Engine, para atacar tu sitio. Es una práctica habitual que los atacantes utilicen servidores virtuales privados (VPS) o instancias de computación de grandes proveedores para enmascarar su origen.

Aquí tienes un desglose de los puntos clave para entender por qué ves esta actividad:

1. googleusercontent.com y los servicios de Google Cloud

  • El dominio googleusercontent.com es utilizado por los clientes de Google para alojar contenido, no por los propios servicios internos de Google.
  • La subsección bc.googleusercontent.com en el nombre de host es una convención para las instancias de Compute Engine de Google que tienen una dirección IP pública.
  • Esto significa que la IP 113.37.83.34 pertenece a un servidor virtual alquilado por un cliente de Google, no a la infraestructura principal de Google.
2. ¿Por qué se utiliza Google Cloud para atacar?
  • Anonimato: Alquilar un servidor en un servicio de nube como Google Cloud permite a los atacantes ocultar su propia dirección IP real detrás de la IP del proveedor de servicios.
  • Facilidad de uso: Las plataformas de nube ofrecen un acceso fácil y rápido para lanzar ataques, como los escaneos XML-RPC que has experimentado.
  • Infraestructura robusta: Los atacantes aprovechan la sólida infraestructura de red de los proveedores de nube para asegurar que sus ataques sean efectivos.

3. ¿Por qué AbuseIPDB la asocia con Google?

  • AbuseIPDB identifica a Google como el propietario del rango de IP, lo cual es correcto desde una perspectiva de registro. Google es el dueño de la infraestructura, pero no el responsable del uso malicioso.
  • Las denuncias leves pueden deberse a que el atacante solo ha usado la IP por un corto período antes de ser detectado, o porque AbuseIPDB solo tiene reportes limitados de la actividad.

4. Qué puedes hacer:

  • Bloquea la IP: Bloquea la dirección IP 113.37.83.34 en tu cortafuegos o en la configuración de seguridad de tu sitio web para detener el escaneo inmediato.
  • Denuncia el abuso: Presenta una denuncia por abuso a Google Cloud Platform (GCP) para que tomen medidas contra el cliente que está utilizando su infraestructura para atacar tu sitio. Ellos tienen políticas estrictas contra el uso indebido.
  • Protege la API XML-RPC: La API XML-RPC es conocida por ser un vector de ataque frecuente. Si no la utilizas, desactívala completamente. Si la necesitas, usa un Plugin que la proteja, la limite o la restrinja para evitar futuros ataques.

Conclusiones

Se mandó casi 2 horas de ataque hasta que me di cuenta y aun así algo sigue ocupando el CPU de mi servidor. Creo que no uso XMLRPC en nada, así que voy a deshabilitarlo. Por otro lado, me parece súper curioso como es que tengo al menos 1 llamada por segundo a mi servidor y aun así, el trafico orgánico es bajísimo. Le tengo dudas hasta a lo que mis estadísticas dicen que es trafico orgánico.

https://interlan.ec/2025/10/15/revisando-los-logs-de-mi-server-xmlrpc-php/

#blog #code2 #devops #seguridad #seguridadInformatica #servidores #vps #wordpress

A decir verdad, ni siquiera sabia que escribir bots de Telegram con Google Script era posible (de hecho, ni sabia que Google Script existía). Pero me viene bien. Es mas seguro que usar el @gmailbot que hace mucho que no me funciona. Después de todo, esto seria mas seguro que andar dando credenciales a desconocidos en internet.

Introducción

La verdad, todo comenzó de una idea era bastante sencilla, necesitaba mandar un correo de una notificación a un grupo familiar apenas llegaba el correo a mi bandeja de entrada. Dado que era una tarea bastante sencilla, no me cabía en la cabeza que fuera imposible de automatizar. Pensé en un inicio en hacer un script con Python o Node, pero la burocracia de la autenticación me aburrió un montón, aparte de lo complicado que es lidiar con IMAP (por mucho que le haya hecho un articulo) así que hice lo que seria sentido común en esta época; preguntarle a la IA. Específicamente a Copilot para Telegram.

Resulta que Gooogle tiene una plataforma llamada App Script, que como describe en su misma pagina, permite ejecutar automatizaciones para todos lo servicios de Google. Puedes utilizarla en cualquiera de tus cuentas de Google y ejecuta una versión de Javascript llamada Google Script que a modo superficial, no les encuentro diferencia alguna. Si bien, no puedes ejecutar programas completos, permite la ejecución regular de tareas, con lo que puedes fácilmente crear un bucle para escanear regularmente tu correo electrónico por novedades y responder acorde a esto. Un bot en toda la regla.

Proyecto Rápido: Reenviar un correo a un grupo de Telegram

Te dejo de tarea la configuración de tu entorno de trabajo. En realidad es bastante sencillo y tendrás que ver tu panel de control en script.google.com y crear un nuevo trabajo. Como código de ejemplo, usare el bot de telegram que hice de forma rápida utilizando la API de Google y Telegram.

1 2 3 4 5 6 7 8 91011121314151617181920212223242526const TELEGRAM_TOKEN = '<tu token>';const CHAT_ID = '<chat id del grupo>';function reenviarCorreosATelegram() { const threads = GmailApp.search('is:unread newer_than:1h TEXTO A BUSCAR'); for (const thread of threads) { const messages = thread.getMessages(); for (const message of messages) { if (!message.isUnread()) continue; const subject = message.getSubject(); const sender = message.getFrom(); const body = message.getPlainBody().substring(0, 300);// Limita el texto const texto = ` Nuevo correo:\nDe: ${sender}\nAsunto: ${subject}\n\n${body}`; const url = `https://api.telegram.org/bot${TELEGRAM_TOKEN}/sendMessage`; const payload = { chat_id: CHAT_ID, text: texto }; UrlFetchApp.fetch(url, { method: 'post', contentType: 'application/json', payload: JSON.stringify(payload) }); message.markRead(); // Opcional: marca como leído } } }

 

Recuerda Cambiar las variables de tu Token, obtenido del botfather y id de grupo, que puedes obtener mediante este código como digo en este articulo

También deberás crear una tarea programada para que el bot se ejecute regularmente. Como este sistema solo permite la ejecución de Scripts, no es posible dejar corriendo alguno de fondo, como normalmente hacernos, así que es un poco limitado en ese sentido a solo enviar mensajes y no recibirlos.

Conclusiones

Este sistema me ha gustado en el sentido de que no necesito un servidor para dejar escaneando los mensajes hasta que llega el que necesito reenviar a Telegram, y que hace bastante ligero trabajar con los correos al ocultar el tedio de usar IMAP mediante clases y métodos específicos para esta tarea. Aun así, esto solo funciona para correos de Google, así que otros servidores carecen de esta funcionalidad. Aun así, me interesa aprender para utilizar con mi servidor propio de correo electrónico.

https://interlan.ec/2025/08/29/tutorial-bots-de-telegram-con-google-script/

#appScript #code2 #desarolloDeBots #gmail #googleMail #googleScript #telegram

ICS Announcer es un bot para Telegram que consulta un calendario público vía WebDAV (formato ICS) y publica automáticamente los eventos del día en el grupo o canal que elijas.

✨ Introducción

A veces no necesitamos una herramienta enorme para una tarea sencilla. Queremos algo que haga una sola cosa y la haga bien. Pero los programas disponibles suelen sentirse como matar moscas a cañonazos.
Por eso creé ICS Announcer: una herramienta ligera, funcional y enfocada. Su único propósito es publicar la lista de eventos diarios en Telegram.

⚙️ Especificaciones técnicas

🧩 El problema

Necesitaba un bot que publicara los eventos diarios en un grupo de Telegram. Al principio pensé hacerlo desde cero, pero no era necesario reinventar la rueda. Ya tenía lo esencial:

  • Un calendario administrado con Nextcloud, accesible públicamente vía CalDAV.
  • Acceso a la API de bots de Telegram.

En vez de mantener un servicio corriendo 24/7, aproveché un enfoque más eficiente: un script que se ejecuta por tarea programada (cron, por ejemplo) solo cuando se necesita.

🚧 Preámbulos: antes de usar

Aunque el código es simple, hay algunos pasos previos.

📅 Calendario (ICS)

Muchos calendarios permiten compartir sus eventos públicamente en formato ICS. ICS Announcer descarga el archivo en cada ejecución, lo que permite reflejar cambios de último momento. Eso sí, depende de tener conexión estable y acceso al calendario.

🤖 Bot de Telegram

Si estás leyendo esto, probablemente ya sepas cómo funciona un bot en Telegram. Si no, puedes crearlo fácilmente usando BotFather, donde obtendrás el token necesario.

Para ayuda adicional, puedes seguir el tutorial oficial.

📝 Configuración (.env)

Crea un archivo .env en el mismo directorio del script con el siguiente contenido:

CAL_URL=https://tucalendario.comTOKEN=el_token_de_tu_botGROUP_ID=id_del_grupo_o_canal

Si no tienes el ID de tu grupo o canal, el script incluye una función que te ayuda a obtenerlo automáticamente al agregar tu bot al grupo.

🗓️ ICS Announcer en acción

Este bot hace solo una cosa: consulta un calendario en línea y publica los eventos en Telegram. Lo sorprendente es que al sacrificar el modelo de servicio, todo se vuelve mucho más sencillo.

Al evitar tener el bot ejecutándose permanentemente, se gana eficiencia y simplicidad. Claro, no es un bot universal que puedan usar todos sin configuración, pero tampoco lo pretende. Su fortaleza está en hacer bien una sola tarea, sin complicaciones ni sobrecargas innecesarias.

1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566import requestsfrom datetime import datetime, timedeltafrom ics import Calendarfrom telegram import Botimport asynciofrom pytz import timezonefrom dotenv import load_dotenvimport osload_dotenv()WEB_DAV_URL=os.environ.get("CAL_URL")TELEGRAM_TOKEN=os.environ.get("TOKEN")GROUP_ID=os.environ.get("GROUP_ID")# Función para obtener eventos del díadef obtener_eventos_del_dia(): # Descargar el archivo .ics response = requests.get(WEB_DAV_URL) response.raise_for_status() calendario = Calendar(response.text) # Definir inicio y fin del día hoy = datetime.now() inicio_dia = datetime(hoy.year, hoy.month, hoy.day, 0, 0, 0) fin_dia = inicio_dia + timedelta(days=1) eventos_hoy = [] for event in calendario.events: # La librería ics parsea fechas en timezone-aware o naive # Convertir a datetime sin timezone para comparación start = event.begin.replace(tzinfo=None) end = event.end.replace(tzinfo=None) if start >= inicio_dia.astimezone(timezone('UTC')) and start < fin_dia.astimezone(timezone('UTC')): eventos_hoy.append(event) return eventos_hoy# Función para crear mensaje con eventosdef crear_mensaje_eventos(eventos): if not eventos: print("No hay eventos para hoy") return "No hay eventos programados para hoy." mensaje = "Eventos para hoy:\n\n" for event in eventos: start_time = event.begin.strftime('%H:%M') print(event) titulo = event.name descripcion= event.description ubicacion= event.location mensaje += f"-- {start_time}: {titulo}\n\n" mensaje += f"Lugar: {ubicacion}\n\n" mensaje += f"{descripcion}\n\n" print(mensaje) return mensajeasync def main(): # Obtener eventos del día eventos = obtener_eventos_del_dia() mensaje = crear_mensaje_eventos(eventos) # Enviar mensaje al grupo de Telegram bot = Bot(token=TELEGRAM_TOKEN) await bot.send_message(chat_id=GROUP_ID, text=mensaje)if __name__ == "__main__": asyncio.run(main())

El ultimo paso ya solo es programar una tarea con cron o alguna herramienta equivalente y el bot quedara trabajando de forma regular, enviando los eventos leidos de un calendario web a un grupo o canal de telegram

https://interlan.ec/2025/07/18/desarrollo-de-bots-ics-announcer/

#bot #caldav #calendario #code2 #ics #programacion #python #telegram

Tengo una tableta Huion que conseguí hace muchos años por Banggood. Para lo que necesito es muy buena, pero en Linux tiene problemas para su funcionamiento. He encontrado una solución y la quiero conservar para que no se pierda.

El problema

Al tener múltiples monitores, algunas funciones cambian. El visor VNC puede mostrar solo uno o mostrar en una sola pantalla los dos, haciéndolo muy poco practico, las tabletas digitalizadoras son reconocidas como un cursor que va de un extremo de la primera pantalla al otro extremo de la segunda, etc. Esto es normal pues XOrg ya es muy viejo y lo seguimos usando para cosas que ni existían cuando fue creado. No tengo idea de si esta respuesta aplique a Wayland, que es mas moderno, pero apenas tenga la oportunidad lo probaré.

La solución

He encontrado la solución en AskUbuntu del usuario binarycat que si bien resuelve el problema en la tableta Huion, solo lo hace en ese momento. al reiniciar hay que volver a ejecutar el script.

El problema mas claro del script es que hay que ejecutar varios comandos para obtener los datos necesarios, como por ejemplo, como es llamado en el sistema el dispositivo en el campo PAD_NAMEy como esta nombrado el MONITOR en XOrg. Lo peor es que estos datos pueden cambiar no solo entre configuraciones de hardware, sino tambien entre cada reinicio.

Afortunadamente parece que ya es mas fácil pues hay mejores herramientas. Aun asi es divertido ver como funcionan estas cosas de la forma mas artesanal posible y también es interesante notar como linux aunque no lo saque perfecto a la primera, siempre consigue hacer funcionar las cosas. Claro, con retoques posteriores.

https://askubuntu.com/questions/839161/limit-a-graphics-tablet-to-one-monitor

Como actualización, parece que hay un código en github que resuelve el problema de forma mas intuitiva aquí

http://wenhsinjen.github.io/ptxconf/

Como no quiero que esta respuesta se me vuelva a perder, adjunto su contenido:

1 2 3 4 5 6 7 8 91011121314151617#!/bin/sh #Change DVI-I-1 to what monitor you want from running command: xrandr MONITOR="DVI-I-1" PAD_NAME='HUION H420 Pad pad' #undo xsetwacom --set "$PAD_NAME" Button 1 "key +ctrl +z -z -ctrl" #define next 2 however you like, I have mine mapped for erase in krita xsetwacom --set "$PAD_NAME" Button 2 "key e" xsetwacom --set "$PAD_NAME" Button 3 "key h" ID_STYLUS=`xinput | grep "Pen stylus" | cut -f 2 | cut -c 4-5` xinput map-to-output $ID_STYLUS $MONITOR exit 0

 

Hey, !parece que ya tengo una cantidad significativa de post relacionados al tema de Solución de Problemas!

https://interlan.ec/2025/06/06/resolucion-de-problemas-tableta-huion-se-extiende-a-multiples-monitores/

#change #code2 #define #huion #resolucionDeProblemas #solucionDeProblemas #tabletaDigitalizadora #troubleshoting #undo #xorg