<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Linux Sin Humo (Publicaciones sobre serie)</title><link>https://sergiobelkin.com/</link><description></description><atom:link href="https://sergiobelkin.com/categories/cat_serie.xml" rel="self" type="application/rss+xml"></atom:link><language>es</language><copyright>Contents © 2026 &lt;a href="mailto:sebelk@gmail.com"&gt;sebelk&lt;/a&gt; 
&lt;a rel="license" href="https://creativecommons.org/licenses/by-nc-sa/4.0/"&gt;
&lt;img alt="Creative Commons License BY-NC-SA"
style="border-width:0; margin-bottom:12px;"
src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png"&gt;&lt;/a&gt;
</copyright><lastBuildDate>Sun, 19 Apr 2026 00:13:28 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>3 Power Tips + Power Link I10</title><link>https://sergiobelkin.com/posts/3-power-tips-power-link-i10/</link><dc:creator>sebelk</dc:creator><description>&lt;figure&gt;&lt;img src="https://sergiobelkin.com/images/PowerTipsPlus.png"&gt;&lt;/figure&gt; &lt;p&gt;Las herramientas de &lt;strong&gt;monitoreo&lt;/strong&gt; son fundamentales, pero una pobre &lt;strong&gt;interpretación&lt;/strong&gt; de los resultados, pueden llevar a conclusiones incorrectas. Incluso usando chatbots de IA, si hacemos &lt;strong&gt;preguntas&lt;/strong&gt; deficientes podemos terminar girando en círculos o tardar más tiempo en resolver un problema. Lo mejor es reducir el nivel de especulación con hipótesis técnica. A continuación vemos unos ejemplos bien sencillos.&lt;/p&gt;
&lt;h3 id="power-tip-1"&gt;Power Tip #1&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;No todas las métricas que parecen similares describen el mismo fenómeno.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Aplicación lenta.&lt;/li&gt;
&lt;li&gt;Load 15.&lt;/li&gt;
&lt;li&gt;CPU idle 50%.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Alguien descarta CPU porque “está libre”.&lt;/p&gt;
&lt;p&gt;Pero:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Load describe tareas en ejecución o esperando.&lt;/li&gt;
&lt;li&gt;CPU usage describe tiempo ocupado.&lt;/li&gt;
&lt;li&gt;CPU pressure describe tiempo en que las tareas no pudieron progresar.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Son fenómenos distintos.&lt;/p&gt;
&lt;p&gt;Antes de interpretar, mirá comportamiento:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;vmstat&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;
mpstat&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Y si necesitás otra capa:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;cat&lt;span class="w"&gt; &lt;/span&gt;/proc/pressure/cpu
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Es importante saber que “Load no es necesariamente consumo de CPU”, sin embargo, más importante es entender qué está describiendo cada señal.&lt;/p&gt;
&lt;p&gt;Interpretarlas como si hablaran de lo mismo es especulación con números.&lt;/p&gt;
&lt;h3 id="power-tip-2"&gt;Power Tip #2&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Tomar una métrica aislada de memoria en Linux no implica entender como funciona&lt;/strong&gt;&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;free&lt;span class="w"&gt; &lt;/span&gt;-h
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Las columnas están ahí. Pero entender qué representa cada una es otra cosa.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;used&lt;/code&gt; no significa “memoria en crisis”.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;buff/cache&lt;/code&gt; no significa “desperdicio”.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;available&lt;/code&gt; no significa “memoria libre inmediata”.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Antes de reaccionar ante un número alto, mirá dinámica:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;vmstat&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Linux administra memoria como recurso dinámico, no como espacio estático.&lt;/p&gt;
&lt;p&gt;Leer columnas sin entender el modelo del kernel es especulación con formato tabular.&lt;/p&gt;
&lt;h3 id="power-tip-3"&gt;Power Tip #3&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Reiniciar en muchas situaciones no hace otra cosa que restaurar un estado. No explica causas.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;El servicio falla.&lt;/li&gt;
&lt;li&gt;Se reinicia.&lt;/li&gt;
&lt;li&gt;Funciona.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Eso no es diagnóstico.&lt;/p&gt;
&lt;p&gt;Antes de repetir el gesto automático:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;journalctl&lt;span class="w"&gt; &lt;/span&gt;-u&lt;span class="w"&gt; &lt;/span&gt;servicio-problematico&lt;span class="w"&gt; &lt;/span&gt;-n&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;50&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Si no entendemos por qué se degradó, volverá a pasar.&lt;/p&gt;
&lt;p&gt;Reiniciar elimina el síntoma. No valida la hipótesis. Las herramientas no están equivocadas.&lt;/p&gt;
&lt;p&gt;La diferencia está en entender qué fenómeno describe cada señal. Está claro que en el mundo real, muchas veces determinar la causa del problema lleva más tiempo que usar un trigger que reinice un servicio. Algo que pasa muchas veces apps legacy (la falta de especialistas o la triste realidad de falta del código fuente). Sin embargo, el problema es cuando se usa esta metodologìa como primera opción...&lt;/p&gt;
&lt;h3 id="power-link"&gt;Power Link&lt;/h3&gt;
&lt;p&gt;La IA terminará con las operaciones de IT. ¿En serio? Bueno, en realidad no, para sorpresa de tecno-optimistas o tecno-pesimistas, aquí hay un interesante análisis de Sebastián Martínez de SUSE sobre este tema: &lt;a href="https://www.suse.com/c/why-ai-cannot-run-linux-infrastructure-mcp-suse/"&gt;Why AI Still Cannot Run Your Linux Infrastructure (And What Must Change)&lt;/a&gt;&lt;/p&gt;</description><category>bash</category><guid>https://sergiobelkin.com/posts/3-power-tips-power-link-i10/</guid><pubDate>Sat, 21 Feb 2026 16:57:09 GMT</pubDate></item><item><title>3 Power Tips + 1 Power Link I9</title><link>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i9/</link><dc:creator>sebelk</dc:creator><description>&lt;figure&gt;&lt;img src="https://sergiobelkin.com/images/PowerTipsPlus.png"&gt;&lt;/figure&gt; &lt;p&gt;&lt;strong&gt;PSI (Pressure Stall Information)&lt;/strong&gt; permite observar ese tipo de situaciones y, sobre todo, cambiar la forma en que interpretamos problemas de rendimiento y estabilidad en Linux. A partir de esa señal, el foco deja de estar en métricas globales y pasa a decisiones concretas: entender dónde ocurre el problema, a quién afecta y cómo intervenir sin arrastrar todo el sistema.
Finalmente, el Power Link nos lleva a ver qué opina Gaël Duval, el creador de la distribución Mandrake, sobre uno de los hypes actuales.&lt;/p&gt;
&lt;h3 id="power-tip-1-como-se-ven-afectadas-mis-aplicaciones-por-falta-de-recursos"&gt;Power Tip #1: ¿Cómo se ven afectadas mis aplicaciones por falta de recursos?&lt;/h3&gt;
&lt;p&gt;Existe a veces una creencia basado en pensamiento mágico: que el monitoreo depende solamente de la herramienta que se utilice. Pero más que la herramienta lo importante, es &lt;em&gt;qué se mide&lt;/em&gt; y &lt;em&gt;cómo interpretar&lt;/em&gt; esos resultados. &lt;strong&gt;Las métricas más conocidas: uso de cpu, load-average, uso de memoria, uso de I/O, etc. si bien son útiles pueden darnos en muchos casos un panorama parcial&lt;/strong&gt;. Eso sucede porque están basados en los recursos, o en el scheduler.&lt;/p&gt;
&lt;p&gt;Existen sin embargo desde hace varios años métricas que están más centradas en como las aplicaciones se ven impactadas por el uso de recursos.  Con PSI (Pressure Stall Information) obtenemos un indicio del tiempo que las aplicaciones quedan detenidas porque el sistema no puede darles CPU, memoria o acceso a disco en el momento en que lo necesitan. &lt;/p&gt;
&lt;p&gt;Esto está expuesto en el sistema de archivos:&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/psi-files.webp"&gt;&lt;img src="https://sergiobelkin.com/images/psi-files.thumbnail.webp" alt="Archivos de PSI"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;PSI distingue entre situaciones donde al menos una tarea queda bloqueada (&lt;code&gt;some&lt;/code&gt;) y escenarios donde todas las tareas relevantes compiten por el mismo recurso (&lt;code&gt;full&lt;/code&gt;).
Valores elevados y sostenidos en este &lt;code&gt;full&lt;/code&gt; caso suelen indicar un problema estructural: no de picos puntuales, sino de diseño, aislamiento o priorización de workloads.&lt;/p&gt;
&lt;p&gt;Vale hacer aquí tres aclaraciones:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Esta funcionalidad está presente a partir de la versión 4.20 del kernel (RHEL8 la trae como backport). En algunas distribuciones puede ser necesario habilitar PSI explícitamente en el arranque.&lt;/li&gt;
&lt;li&gt;Esta no es &lt;strong&gt;la&lt;/strong&gt; métrica definitiva, sin embargo ignorarla es perder el cuadro completo de lo que sucede tanto en el sistema como nuestras aplicaciones.&lt;/li&gt;
&lt;li&gt;Versiones recientes del kernel incluyen también la medición de la presión sobre &lt;strong&gt;irq&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="power-tip-2-las-disrupciones-se-pueden-atribuir-a-workloads-especificos"&gt;Power Tip #2: Las disrupciones se pueden atribuir a workloads específicos&lt;/h3&gt;
&lt;p&gt;Cuando el host empieza a perder capacidad de respuesta, no siempre el problema es global.
Es común que el sistema siga siendo usable mientras algunos servicios o aplicaciones comienzan a degradarse, simplemente porque no acceden a los recursos cuando los necesitan. Esa degradación suele manifestarse como lentitud, mayor latencia o pérdida de capacidad de interacción.&lt;/p&gt;
&lt;p&gt;En un Linux moderno, el kernel organiza los procesos bajo &lt;strong&gt;dominios de control definidos por cgroups&lt;/strong&gt;.
Esto permite observar de forma localizada qué tareas empiezan a quedarse esperando recursos, en lugar de razonar únicamente a partir de métricas agregadas del host.&lt;/p&gt;
&lt;p&gt;En sistemas basados en systemd, ese dominio no es abstracto: se corresponde con services, slices o scopes.
El mismo síntoma que aparece a nivel global puede observarse dentro de estos límites, lo que permite atribuir dónde se generan las esperas, incluso cuando el resto del sistema continúa funcionando con normalidad.&lt;/p&gt;
&lt;p&gt;Pensar a nivel host diluye el diagnóstico.
En cambio poner el foco en en services, scopes y slices permite relacionar directamente los síntomas percibidos —lentitud, tiempos de respuesta, degradación de rendimiento— con un grupo de procesos concreto.&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/specific-psi.webp"&gt;&lt;img src="https://sergiobelkin.com/images/specific-psi.thumbnail.webp" alt="PSI per cgroup"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Es decir, uno puede decir que &lt;strong&gt;el host muestra la presión acumulada&lt;/strong&gt;, pero &lt;strong&gt;los cgroups permiten entender qué se queda atascado y frente qué recurso&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id="power-tip-3-abordar-el-problema-de-manera-localizada"&gt;Power Tip #3: Abordar el problema de manera localizada&lt;/h3&gt;
&lt;p&gt;Cuando un servicio o aplicación empieza a tener tiempos muertos o a interferir con el resto, tenemos varias maneras de abordar el problema. Y no estamos hablando de las típicas acciones: reiniciarlo, moverlo o rediseñarlo.&lt;/p&gt;
&lt;p&gt;Podemos tomar medidas más estructurales, por ejemplo, crear un slice de systemd, establecer límites y luego confinar esos servicios o procesos en esos slices.&lt;/p&gt;
&lt;p&gt;Sin embargo, antes de intervenir de manera prematura, es conveniente tener en cuenta que Linux, en general ya tiene una agrupación de slices, scopes y servicios bastante razonable. En este punto entonces, ya sabemos que &lt;strong&gt;ese servicio problemático ya corre dentro de un perímetro definido&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;En lugar de crear un nuevo slice, que tiene un carácter más permanente, podemos adoptar una solución más sencilla y gradualista. En systemd, &lt;strong&gt;los parámetros que gobiernan cómo compite por recursos no están fijos&lt;/strong&gt; en scopes o servicios.&lt;/p&gt;
&lt;p&gt;Un vistazo rápido alcanza para verlo (los siguientes son ejemplos para entender la idea):&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;systemctl&lt;span class="w"&gt; &lt;/span&gt;show&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;ControlGroup,CPUWeight,MemoryMax,IOWeight&lt;span class="w"&gt; &lt;/span&gt;procesos-ruidosos.scope
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Y tomar cartas en el asunto:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;systemctl&lt;span class="w"&gt; &lt;/span&gt;set-property&lt;span class="w"&gt; &lt;/span&gt;procesos-ruidosos.scope&lt;span class="w"&gt; &lt;/span&gt;…
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Ese tipo de intervención es local, reversible y no convierte un incidente puntual en un cambio estructural.&lt;/p&gt;
&lt;p&gt;Intervenir sobre una unidad existente permite corregir interferencias concretas &lt;strong&gt;sin rediseñar el sistema ni propagar el problema&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id="fuentes-y-mas-recursos"&gt;Fuentes y más recursos&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://sergiobelkin.com/posts/que-son-los-cgroups-y-para-que-sirven/"&gt;Qué son los cgroups y para qué sirven&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="power-link"&gt;Power Link&lt;/h3&gt;
&lt;p&gt;Gaël Duval, creador de Mandrake, Murena y e/OS reflexiona sobre el impacto de la AI en el software open source: &lt;a href="https://gaelduval.com/why-ai-wont-kill-open-source/#more-1725"&gt;Why AI won’t “Kill Open Source”&lt;/a&gt;&lt;/p&gt;</description><category>bash</category><guid>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i9/</guid><pubDate>Sun, 04 Jan 2026 18:30:54 GMT</pubDate></item><item><title>3 Power Tips + 1 Power Link I8</title><link>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i8/</link><dc:creator>sebelk</dc:creator><description>&lt;figure&gt;&lt;img src="https://sergiobelkin.com/images/PowerTipsPlus.png"&gt;&lt;/figure&gt; &lt;p&gt;&lt;strong&gt;Resumen&lt;/strong&gt;: En esta entrega, un ejemplo del poder que tienen la subshells de bash, como solucionar problemas de SELinux con podman, y el uso de la herramienta yq para procesar archivos yaml.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Nota: En los ejemplos de comandos el prompt del usuario no privilegiado es "$", mientras que el del superusuario es "#"&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="power-tip-1-crear-entornos-de-bash-efimeros-usando-subshells"&gt;Power Tip #1: Crear entornos de bash efímeros usando subshells&lt;/h3&gt;
&lt;p&gt;Una subshell es una copia del proceso de la shell actual. Una manera de crear una subshell es usando &lt;code&gt;()&lt;/code&gt; y sirve: para personalizar el entorno de bash de manera reversible. Por ejemplo, podemos cambiar de directorio y la variable de entorno C (POSIX) para que muestre los mensajes de salida y de error en inglés:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LANG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
es_AR.UTF-8
$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;
/home/sergio
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Ahora creamos una &lt;strong&gt;subshell&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;LANG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;C&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"La variable LANG cambia a  &lt;/span&gt;&lt;span class="nv"&gt;$LANG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/algun_dir&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/tmp&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"el directorio actual es &lt;/span&gt;&lt;span class="nv"&gt;$PWD&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;myscript.sh&lt;span class="o"&gt;)&lt;/span&gt;
La&lt;span class="w"&gt; &lt;/span&gt;variable&lt;span class="w"&gt; &lt;/span&gt;LANG&lt;span class="w"&gt; &lt;/span&gt;cambia&lt;span class="w"&gt; &lt;/span&gt;a&lt;span class="w"&gt;  &lt;/span&gt;C
-bash:&lt;span class="w"&gt; &lt;/span&gt;cd:&lt;span class="w"&gt; &lt;/span&gt;/algun_dir:&lt;span class="w"&gt; &lt;/span&gt;No&lt;span class="w"&gt; &lt;/span&gt;such&lt;span class="w"&gt; &lt;/span&gt;file&lt;span class="w"&gt; &lt;/span&gt;or&lt;span class="w"&gt; &lt;/span&gt;directory
el&lt;span class="w"&gt; &lt;/span&gt;directorio&lt;span class="w"&gt; &lt;/span&gt;actual&lt;span class="w"&gt; &lt;/span&gt;es&lt;span class="w"&gt; &lt;/span&gt;/tmp
-bash:&lt;span class="w"&gt; &lt;/span&gt;myscript.sh:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;command&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;not&lt;span class="w"&gt; &lt;/span&gt;found
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Al terminar la subshell, volvemos a la shell madre y tanto el directorio de trabajo como la variable LANG, vuelven a sus valores predeterminados:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;
/home/sergio
$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LANG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
es_AR.UTF-8
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="power-tip-2-identificar-y-solucionar-problemas-de-selinux-al-usar-volumenes"&gt;Power Tip #2: Identificar y solucionar problemas de SELinux al usar volúmenes.&lt;/h3&gt;
&lt;p&gt;Supongamos que necesitamos probar una configuración en un contenedor:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;$&lt;span class="w"&gt; &lt;/span&gt;podman&lt;span class="w"&gt; &lt;/span&gt;run&lt;span class="w"&gt;  &lt;/span&gt;--name&lt;span class="w"&gt; &lt;/span&gt;mynginx&lt;span class="w"&gt;  &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;-v&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/sandbox/nginx.conf:/etc/nginx/nginx.conf&lt;span class="w"&gt; &lt;/span&gt;--pull&lt;span class="o"&gt;=&lt;/span&gt;never&lt;span class="w"&gt; &lt;/span&gt;docker.io/library/nginx@sha256:553f64aecdc31b5bf944521731cd70e35da4faed96b2b7548a3d8e2598c52a42
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Ahora bien: ¿Qué sucede si el contenedor en realidad, falla al arrancar como lo muestran los logs?:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;$&lt;span class="w"&gt; &lt;/span&gt;podman&lt;span class="w"&gt; &lt;/span&gt;logs&lt;span class="w"&gt; &lt;/span&gt;mynginx&lt;span class="w"&gt; &lt;/span&gt;
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;/docker-entrypoint.d/&lt;span class="w"&gt; &lt;/span&gt;is&lt;span class="w"&gt; &lt;/span&gt;not&lt;span class="w"&gt; &lt;/span&gt;empty,&lt;span class="w"&gt; &lt;/span&gt;will&lt;span class="w"&gt; &lt;/span&gt;attempt&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;perform&lt;span class="w"&gt; &lt;/span&gt;configuration
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;Looking&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;shell&lt;span class="w"&gt; &lt;/span&gt;scripts&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/docker-entrypoint.d/
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;Launching&lt;span class="w"&gt; &lt;/span&gt;/docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
&lt;span class="m"&gt;10&lt;/span&gt;-listen-on-ipv6-by-default.sh:&lt;span class="w"&gt; &lt;/span&gt;info:&lt;span class="w"&gt; &lt;/span&gt;Getting&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;checksum&lt;span class="w"&gt; &lt;/span&gt;of&lt;span class="w"&gt; &lt;/span&gt;/etc/nginx/conf.d/default.conf
&lt;span class="m"&gt;10&lt;/span&gt;-listen-on-ipv6-by-default.sh:&lt;span class="w"&gt; &lt;/span&gt;info:&lt;span class="w"&gt; &lt;/span&gt;Enabled&lt;span class="w"&gt; &lt;/span&gt;listen&lt;span class="w"&gt; &lt;/span&gt;on&lt;span class="w"&gt; &lt;/span&gt;IPv6&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/etc/nginx/conf.d/default.conf
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;Sourcing&lt;span class="w"&gt; &lt;/span&gt;/docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;Launching&lt;span class="w"&gt; &lt;/span&gt;/docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;Launching&lt;span class="w"&gt; &lt;/span&gt;/docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;Configuration&lt;span class="w"&gt; &lt;/span&gt;complete&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ready&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;start&lt;span class="w"&gt; &lt;/span&gt;up
&lt;span class="m"&gt;2025&lt;/span&gt;/11/24&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;20&lt;/span&gt;:09:21&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;emerg&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="c1"&gt;#1: open() "/etc/nginx/nginx.conf" failed (13: Permission denied)&lt;/span&gt;
nginx:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;emerg&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;open&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/etc/nginx/nginx.conf"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;failed&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;13&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;Permission&lt;span class="w"&gt; &lt;/span&gt;denied&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Si estás tentado a desactivar SELinux, te recomiendo enfáticamente que leas &lt;a href="https://sergiobelkin.com/posts/selinux-nah-deshabilitalo/"&gt;¿SELinux? Nah, dejalo en Disabled&lt;/a&gt;. Lo que ocurre es que no hay ninguna regla que permita que el contenedor acceda al contexto del archivo nginx.conf del host.&lt;/p&gt;
&lt;p&gt;Contexto del archivo:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;$&lt;span class="w"&gt; &lt;/span&gt;ls&lt;span class="w"&gt; &lt;/span&gt;-Z&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/sandbox/nginx.conf
unconfined_u:object_r:user_home_t:s0&lt;span class="w"&gt; &lt;/span&gt;/home/sergio/sandbox/nginx.conf
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Este problema se soluciona fácilmente:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="sb"&gt;```&lt;/span&gt;bash
podman&lt;span class="w"&gt; &lt;/span&gt;stop&lt;span class="w"&gt; &lt;/span&gt;mynginx
podman&lt;span class="w"&gt; &lt;/span&gt;rm&lt;span class="w"&gt; &lt;/span&gt;mynginx
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Y ahora el contenedor arrancará sin inconvenientes:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;podman&lt;span class="w"&gt; &lt;/span&gt;ps
CONTAINER&lt;span class="w"&gt; &lt;/span&gt;ID&lt;span class="w"&gt;  &lt;/span&gt;IMAGE&lt;span class="w"&gt;                                                                                            &lt;/span&gt;COMMAND&lt;span class="w"&gt;               &lt;/span&gt;CREATED&lt;span class="w"&gt;         &lt;/span&gt;STATUS&lt;span class="w"&gt;         &lt;/span&gt;PORTS&lt;span class="w"&gt;       &lt;/span&gt;NAMES
a29c08eda1b1&lt;span class="w"&gt;  &lt;/span&gt;docker.io/library/nginx@sha256:553f64aecdc31b5bf944521731cd70e35da4faed96b2b7548a3d8e2598c52a42&lt;span class="w"&gt;  &lt;/span&gt;nginx&lt;span class="w"&gt; &lt;/span&gt;-g&lt;span class="w"&gt; &lt;/span&gt;daemon&lt;span class="w"&gt; &lt;/span&gt;o...&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;seconds&lt;span class="w"&gt; &lt;/span&gt;ago&lt;span class="w"&gt;  &lt;/span&gt;Up&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;seconds&lt;span class="w"&gt;              &lt;/span&gt;mynginx
podman&lt;span class="w"&gt; &lt;/span&gt;logs&lt;span class="w"&gt; &lt;/span&gt;mynginx&lt;span class="w"&gt; &lt;/span&gt;
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;/docker-entrypoint.d/&lt;span class="w"&gt; &lt;/span&gt;is&lt;span class="w"&gt; &lt;/span&gt;not&lt;span class="w"&gt; &lt;/span&gt;empty,&lt;span class="w"&gt; &lt;/span&gt;will&lt;span class="w"&gt; &lt;/span&gt;attempt&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;perform&lt;span class="w"&gt; &lt;/span&gt;configuration
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;Looking&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;shell&lt;span class="w"&gt; &lt;/span&gt;scripts&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/docker-entrypoint.d/
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;Launching&lt;span class="w"&gt; &lt;/span&gt;/docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
&lt;span class="m"&gt;10&lt;/span&gt;-listen-on-ipv6-by-default.sh:&lt;span class="w"&gt; &lt;/span&gt;info:&lt;span class="w"&gt; &lt;/span&gt;Getting&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;checksum&lt;span class="w"&gt; &lt;/span&gt;of&lt;span class="w"&gt; &lt;/span&gt;/etc/nginx/conf.d/default.conf
&lt;span class="m"&gt;10&lt;/span&gt;-listen-on-ipv6-by-default.sh:&lt;span class="w"&gt; &lt;/span&gt;info:&lt;span class="w"&gt; &lt;/span&gt;Enabled&lt;span class="w"&gt; &lt;/span&gt;listen&lt;span class="w"&gt; &lt;/span&gt;on&lt;span class="w"&gt; &lt;/span&gt;IPv6&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/etc/nginx/conf.d/default.conf
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;Sourcing&lt;span class="w"&gt; &lt;/span&gt;/docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;Launching&lt;span class="w"&gt; &lt;/span&gt;/docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;Launching&lt;span class="w"&gt; &lt;/span&gt;/docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;Configuration&lt;span class="w"&gt; &lt;/span&gt;complete&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ready&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;start&lt;span class="w"&gt; &lt;/span&gt;up
&lt;span class="m"&gt;2025&lt;/span&gt;/11/24&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;21&lt;/span&gt;:16:10&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;notice&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="c1"&gt;#1: using the "epoll" event method&lt;/span&gt;
&lt;span class="m"&gt;2025&lt;/span&gt;/11/24&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;21&lt;/span&gt;:16:10&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;notice&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="c1"&gt;#1: nginx/1.29.3&lt;/span&gt;
&lt;span class="m"&gt;2025&lt;/span&gt;/11/24&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;21&lt;/span&gt;:16:10y&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;notice&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="c1"&gt;#1: built by gcc 14.2.0 (Debian 14.2.0-19) &lt;/span&gt;
&lt;span class="m"&gt;2025&lt;/span&gt;/11/24&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;21&lt;/span&gt;:16:10&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;notice&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="c1"&gt;#1: OS: Linux 4.18.0-553.84.1.el8_10.x86_64&lt;/span&gt;
&lt;span class="m"&gt;2025&lt;/span&gt;/11/24&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;21&lt;/span&gt;:16:10&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;notice&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="c1"&gt;#1: getrlimit(RLIMIT_NOFILE): 262144:262144&lt;/span&gt;
&lt;span class="m"&gt;2025&lt;/span&gt;/11/24&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;21&lt;/span&gt;:16:10&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;notice&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="c1"&gt;#1: start worker processes&lt;/span&gt;
&lt;span class="m"&gt;2025&lt;/span&gt;/11/24&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;21&lt;/span&gt;:16:10&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;notice&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="c1"&gt;#1: start worker process 28&lt;/span&gt;
&lt;span class="m"&gt;2025&lt;/span&gt;/11/24&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;21&lt;/span&gt;:16:10&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;notice&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="c1"&gt;#1: start worker process 29&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Ahora bien, la opción &lt;code&gt;:Z&lt;/code&gt; no es mágica, para tener una aproximación a lo que hace veamos el contexto del archivo $HOME/sandbox/nginx.conf:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;$&lt;span class="w"&gt; &lt;/span&gt;ls&lt;span class="w"&gt; &lt;/span&gt;-Z&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/sandbox/nginx.conf
system_u:object_r:container_file_t:s0:c369,c839&lt;span class="w"&gt; &lt;/span&gt;/home/sergio/sandbox/nginx.conf
&lt;/pre&gt;&lt;/div&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Campo&lt;/th&gt;
&lt;th&gt;Antes&lt;/th&gt;
&lt;th&gt;Después&lt;/th&gt;
&lt;th&gt;Comentario&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Usuario (SELinux)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;unconfined_u&lt;/td&gt;
&lt;td&gt;system_u&lt;/td&gt;
&lt;td&gt;Pasa de ser un usuario sin restricciones a un usuario gestionado por el sistema&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rol (SELinux)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;object_r&lt;/td&gt;
&lt;td&gt;object_r&lt;/td&gt;
&lt;td&gt;Se mantiene sin cambios&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Asignación basada en tipos&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;user_home_t&lt;/td&gt;
&lt;td&gt;container_file_t&lt;/td&gt;
&lt;td&gt;Cambia a un tipo de asignación en la cual los contenedores pueden escribir&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rango (SELinux)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;s0&lt;/td&gt;
&lt;td&gt;s0:c369,c839&lt;/td&gt;
&lt;td&gt;Este cambio implica que solamente podrá utilizarlo de manera exclusiva un único contenedor&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="power-tip-3-filtrar-un-archivo-de-template-en-formato-yaml-de-zabbix-sin-instalar-absolutamente-nada"&gt;Power Tip #3: Filtrar un archivo de template en formato yaml de Zabbix sin instalar absolutamente nada&lt;/h3&gt;
&lt;p&gt;Solamente necesitamos podman, en el siguiente ejemplo estamos filtrando todos los triggers estáticos con nivel de severidad &lt;strong&gt;HIGH&lt;/strong&gt; o &lt;strong&gt;DISASTER&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;podman&lt;span class="w"&gt; &lt;/span&gt;run&lt;span class="w"&gt; &lt;/span&gt;--rm&lt;span class="w"&gt; &lt;/span&gt;-v&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PWD&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;:/workdir:Z&lt;span class="w"&gt; &lt;/span&gt;mikefarah/yq&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s1"&gt;'.zabbix_export.templates[].items[].triggers[] | select(.priority == "HIGH" or .priority == "DISASTER")| {"Trigger": .name}'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;template_db_mssql_agent2.yaml
Trigger:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'MSSQL: Percentage of the buffer cache efficiency is low'&lt;/span&gt;
Trigger:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'MSSQL: Page life expectancy is low'&lt;/span&gt;
Trigger:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'MSSQL: Percentage of work tables available from the work table cache is low'&lt;/span&gt;
Trigger:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'MSSQL: Service is unavailable'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="fuentes-y-mas-recursos"&gt;Fuentes y más recursos&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://danwalsh.livejournal.com/81269.html"&gt;Container Labeling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://danwalsh.livejournal.com/76016.html"&gt;Be careful relabeling volumes with Container run times. Sometimes things can go very wrong?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="power-link"&gt;Power Link&lt;/h3&gt;
&lt;p&gt;El enlace de esta edición apunta a una entrevista a Linux Torvalds que gira en torno a la evolución del hardware, la IA y su impacto en el Linux y el desarrollo del kernel: &lt;a href="https://www.youtube.com/watch?v=NjGHrDnPxwI"&gt;Linus Torvalds — Talks about AI Hype, GPU Power, and Linux’s Future &lt;/a&gt;. En la actualidad cuestiones como la programación guiada por la intuición con la ayuda de chatbots debates importantes, no solamente en Linux sino en el ámbito IT en general.&lt;/p&gt;</description><category>bash</category><guid>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i8/</guid><pubDate>Sun, 23 Nov 2025 22:09:59 GMT</pubDate></item><item><title>3 Power Tips + 1 Power Link I7</title><link>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i7/</link><dc:creator>sebelk</dc:creator><description>&lt;figure&gt;&lt;img src="https://sergiobelkin.com/images/PowerTipsPlus.png"&gt;&lt;/figure&gt; &lt;p&gt;&lt;strong&gt;Resumen&lt;/strong&gt;: Tips para bash, KDE Plasma y el uso del shell para cambiar entre ambientes de desarrollo. Además, en el Power Link, un artículo de Aaron P. MacSween, en el que discute el uso de &lt;em&gt;AI scraping&lt;/em&gt; de sitios web usados de manera no consensuada para entrenar &lt;em&gt;Modelos Extensos de Lenguaje (LLMs)&lt;/em&gt;.&lt;/p&gt;
&lt;h3 id="power-tip-1-agrupacion-de-comandos-en-bash"&gt;Power Tip #1: Agrupación de comandos en bash&lt;/h3&gt;
&lt;p&gt;El shell bash permite agrupar comandos, una funcionalidad tan sencilla como potente, por ejemplo:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;dnf&lt;span class="w"&gt; &lt;/span&gt;-y&lt;span class="w"&gt; &lt;/span&gt;upgrade&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;systemctl&lt;span class="w"&gt; &lt;/span&gt;restart&lt;span class="w"&gt; &lt;/span&gt;httpd&lt;span class="w"&gt; &lt;/span&gt;mariadb&lt;span class="w"&gt; &lt;/span&gt;php-fpm&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The final status is unsuccessful 🙁"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;De esta manera si algunos de los dos comandos falla, mostrará un mensaje de error unificado.&lt;/p&gt;
&lt;h3 id="power-tip-2-uso-de-cuadros-de-dialogos-nativos-de-kde-plasma-en-firefox"&gt;Power Tip #2: Uso de cuadros de diálogos nativos de KDE Plasma en Firefox&lt;/h3&gt;
&lt;p&gt;Para hacerlo hay que abrir la url &lt;code&gt;about:config&lt;/code&gt; y luego setear la preferencia &lt;code&gt;widget.use-xdg-desktop-portal.file-picker&lt;/code&gt; en &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/pt7-set-pref-ff.webp"&gt;&lt;img src="https://sergiobelkin.com/images/pt7-set-pref-ff.thumbnail.webp" alt="Set preferences on Firefox"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Esto se basa en el uso de XDG Portals que es un elemento de la arquitectura de entornos gráficos. Ellos proporcionan sandboxing, funcionalidad en entornos Wayland y lo que nos interesa en este caso: coherencia en la interfaz del usuario.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Antes 🤐&lt;/th&gt;
&lt;th&gt;Después 😎️&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/pt7-ugly-dialog-box-firefox.webp"&gt;&lt;img src="https://sergiobelkin.com/images/pt7-ugly-dialog-box-firefox.thumbnail.webp" alt="Set preferences on Firefox"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/pt7-nice-dialog-box-firefox.webp"&gt;&lt;img src="https://sergiobelkin.com/images/pt7-nice-dialog-box-firefox.thumbnail.webp" alt="Before and After of setting file picker"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Ah... usar la variable de entorno &lt;code&gt;MOZ_USE_XDG_PORTAL&lt;/code&gt; no es la manera recomendada, más allá de lo que diga cierto chatbot...&lt;/p&gt;
&lt;h3 id="power-tip-3-flask-linux-entornos-seguros-usando-solo-la-shell"&gt;Power Tip #3: [Flask + Linux]: Entornos Seguros usando solo la Shell&lt;/h3&gt;
&lt;h4 id="problema-comun"&gt;Problema Común&lt;/h4&gt;
&lt;p&gt;Ejecutar una app Flask con &lt;code&gt;DEBUG=True&lt;/code&gt; en producción expone trazas de errores, rutas internas y detalles del &lt;em&gt;stack&lt;/em&gt; que pueden ser explotados. Un &lt;strong&gt;sysadmin o devops con experiencia&lt;/strong&gt; sabe que una práctica profesional es &lt;strong&gt;externalizar la configuración&lt;/strong&gt; y usar el sistema operativo como interruptor de entorno.&lt;/p&gt;
&lt;h4 id="solucion-basada-en-linux-flask"&gt;Solución Basada en Linux + Flask&lt;/h4&gt;
&lt;p&gt;Usá la variable de entorno de Linux &lt;code&gt;FLASK_ENV&lt;/code&gt; para alternar entre una configuración segura de Producción (&lt;code&gt;config_prod.py&lt;/code&gt;) y una configuración orientada a Desarrollo (&lt;code&gt;config_dev.py&lt;/code&gt;).&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Archivo&lt;/th&gt;
&lt;th&gt;Ajuste Crítico&lt;/th&gt;
&lt;th&gt;Enfoque Operacional&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;config_dev.py&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;DEBUG = True&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Enfoque en depuración y agilidad.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;config_prod.py&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;DEBUG = False&lt;/code&gt;&lt;br&gt;&lt;code&gt;SECRET_KEY = os.environ.get('PROD_KEY')&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Prioridad a la &lt;strong&gt;Seguridad&lt;/strong&gt; y la &lt;strong&gt;Gestión de Secretos&lt;/strong&gt; mediante la &lt;em&gt;shell&lt;/em&gt; de Linux.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="fragmento-de-apppy"&gt;Fragmento de app.py&lt;/h4&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;flask&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;
&lt;span class="c1"&gt;# Se importan las clases para un código robusto:&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;config_dev&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;DevelopmentConfig&lt;/span&gt; 
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;config_prod&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ProductionConfig&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vm"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'FLASK_ENV'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'production'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Entorno PROD: Carga DEBUG=False&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ProductionConfig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Entorno DEV: Carga DEBUG=True por defecto&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DevelopmentConfig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id="control-desde-la-terminal"&gt;Control desde la Terminal&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;Entorno Deseado&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Comando Linux&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Resultado&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Producción&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;export FLASK_ENV=production; python app.py&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;* Debug mode: off&lt;/code&gt; (Modo seguro activado por el &lt;em&gt;shell&lt;/em&gt; de Linux).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Desarrollo&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;unset FLASK_ENV; python app.py&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;* Debug mode: on&lt;/code&gt; (La variable se borra, volviendo al modo de depuración).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;✅ Conclusión:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Este patrón convierte tu &lt;em&gt;shell&lt;/em&gt; de Linux en un &lt;em&gt;switch&lt;/em&gt; seguro de entorno para tu app Flask.&lt;/p&gt;
&lt;h3 id="preguntas-de-repaso"&gt;Preguntas de repaso&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Seguridad y DevOps (Power Tip #3):&lt;/strong&gt; ¿Cuál es el riesgo principal de ejecutar una aplicación Flask con &lt;code&gt;DEBUG=True&lt;/code&gt; en producción, y cómo permite la variable de entorno de Linux &lt;strong&gt;&lt;code&gt;FLASK_ENV&lt;/code&gt;&lt;/strong&gt; que el administrador (&lt;code&gt;sysadmin o devops con experiencia&lt;/code&gt;) cambie de manera segura a la configuración de producción (&lt;code&gt;config_prod.py&lt;/code&gt;) usando solo un comando en la &lt;em&gt;shell&lt;/em&gt;?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Eficiencia en Bash (Power Tip #1):&lt;/strong&gt; En el ejemplo de agrupación de comandos, ¿cuál es el propósito de encerrar las sentencias de actualización (&lt;code&gt;dnf -y upgrade&lt;/code&gt;) y de reinicio de servicios (&lt;code&gt;systemctl restart ...&lt;/code&gt;) entre llaves &lt;code&gt;{}&lt;/code&gt;, y qué rol juega el operador lógico &lt;strong&gt;&lt;code&gt;||&lt;/code&gt;&lt;/strong&gt; en caso de que alguna de estas operaciones falle?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Experiencia de Usuario (Power Tip #2):&lt;/strong&gt; Si un usuario de KDE Plasma desea que Firefox utilice los cuadros de diálogo nativos del escritorio en lugar de los predeterminados del navegador, ¿qué URL debe abrir y a qué valor debe establecer la preferencia &lt;strong&gt;&lt;code&gt;widget.use-xdg-desktop-portal.file-picker&lt;/code&gt;&lt;/strong&gt;?&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="power-link"&gt;Power Link&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://cryptography.dog/blog/AI-scrapers-request-commented-scripts/"&gt;AI scrapers request commented scripts&lt;/a&gt;. ¿Hasta qué punto una actividad es considerada benigina cuando se entrenan LLMs? Y muchas cuestiones para pensar...&lt;/p&gt;</description><category>bash</category><guid>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i7/</guid><pubDate>Tue, 04 Nov 2025 22:10:17 GMT</pubDate></item><item><title>3 Power Tips + 1 Power Link I6</title><link>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i6/</link><dc:creator>sebelk</dc:creator><description>&lt;figure&gt;&lt;img src="https://sergiobelkin.com/images/PowerTipsPlus.png"&gt;&lt;/figure&gt; &lt;p&gt;&lt;strong&gt;Resumen:&lt;/strong&gt; Tips para KDE Plasma, manejo de directorios temporales e información detallada sobre podman. Además, un link a un post en el cual un líder de ingenería recomienda pasar de Docker a Podman.  &lt;/p&gt;
&lt;h3 id="power-tip-1-reiniciar-kde-plasma-sin-cerrar-sesion"&gt;Power Tip #1 Reiniciar KDE Plasma sin cerrar sesión&lt;/h3&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;kquitapp6&lt;span class="w"&gt; &lt;/span&gt;plasmashell&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;plasmashell&lt;span class="w"&gt; &lt;/span&gt;--replace&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;/tmp/plasma.log&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;disown&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-h
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="power-tip-2-crea-un-sandbox-con-limpieza-automatica-usando-tmpfilesd"&gt;Power Tip #2 Crea un sandbox con limpieza automática usando tmpfiles.d&lt;/h3&gt;
&lt;p&gt;Podemos tener un directorio al cual usamos como sandbox, por ejemplo para:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Descarga de archivos&lt;/li&gt;
&lt;li&gt;Volcar Logs y dumps temporarios&lt;/li&gt;
&lt;li&gt;Scripts, código... y cualquier cosa que queremos probar.... por un tiempo.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pero la idea es que no queremos que esos archivos se almacenen de manera indefinida... entonces:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;cat&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;lt;&amp;lt; EOF &amp;gt;  ~/.config/user-tmpfiles.d/user-sandbox.conf &lt;/span&gt;
&lt;span class="s"&gt;&amp;gt; d %h/sandbox - - - 7d&lt;/span&gt;
&lt;span class="s"&gt;&amp;gt; d %h/sandbox/ephemeral - - - 10m&lt;/span&gt;
&lt;span class="s"&gt;&amp;gt; EOF&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Una idea tentadora es usar un directorio como &lt;code&gt;/tmp&lt;/code&gt;. Pero no es buena práctica usar ese directorio como sandbox. Luego de crear ese archivo, hay que ejecutar: &lt;code&gt;systemd-tmpfiles --create --user&lt;/code&gt; que creará los directorios en las rutas especificadas. El servicio &lt;code&gt;systemd-tmpfiles-clean&lt;/code&gt; eliminará periódicamente los archivos más viejos de 7 días del directorio ~/sandbox. El contenido de &lt;code&gt;~/sandbox/ephermeral&lt;/code&gt; en cambio, no se borrará automáticamente excepto que creemos una unit de tipo timer. Sin embargo se puede hacer manualmente mediante &lt;code&gt;systemd-tmpfiles --clean --user&lt;/code&gt;. Como siempre entender por qué hacés lo que hacés es fundamental, los manpages son siempre aliados a tener en cuenta aun en pleno hype de la AI.&lt;/p&gt;
&lt;p&gt;A propósito... el comando en el PowerTip #1 podría haber usado el directorio del sandbox en lugar de /tmp....&lt;/p&gt;
&lt;h3 id="power-tip-3-revisar-espacios-y-objetos-de-manera-detallada-en-podman"&gt;Power Tip #3 Revisar espacios y objetos de manera detallada en Podman&lt;/h3&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;podman&lt;span class="w"&gt; &lt;/span&gt;system&lt;span class="w"&gt; &lt;/span&gt;df&lt;span class="w"&gt; &lt;/span&gt;-v
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;De esta manera obtenemos información muy útil sobre las imágenes, contenedores y volúmenes que tenemos.&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/pt6-podman-system-df.webp"&gt;&lt;img src="https://sergiobelkin.com/images/pt6-podman-system-df.thumbnail.webp" alt="Espacio ocupado por podman"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h4 id="power-link"&gt;Power Link&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://www.odbms.org/blog/2025/10/beyond-the-ai-hype-guido-van-rossum-on-pythons-philosophy-simplicity-and-the-future-of-programming/"&gt;Entrevista a Guido van Rossum, creador de Python, en la cual trata entre temas sobre AI&lt;/a&gt;&lt;/p&gt;</description><category>bash</category><guid>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i6/</guid><pubDate>Mon, 13 Oct 2025 21:13:07 GMT</pubDate></item><item><title>3 Power Tips + 1 Power Link I5</title><link>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i5/</link><dc:creator>sebelk</dc:creator><description>&lt;figure&gt;&lt;img src="https://sergiobelkin.com/images/PowerTipsPlus.png"&gt;&lt;/figure&gt; &lt;p&gt;&lt;strong&gt;Resumen:&lt;/strong&gt; Tips para containers, uso de digests y análisis de seguridad de imágenes y obtener información de imágenes remotas. Además, un link a un post en el cual un líder de ingenería recomienda pasar de Docker a Podman.  &lt;/p&gt;
&lt;h3 id="power-tip-1-etiquetar-las-imagenes-con-digest-en-produccion"&gt;Power Tip #1 Etiquetar las imágenes con digest en producción&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;❌ Mala práctica, apuntar a un tag:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;podman&lt;span class="w"&gt; &lt;/span&gt;run&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;--name&lt;span class="w"&gt; &lt;/span&gt;pass_git&lt;span class="w"&gt; &lt;/span&gt;localhost/passteiner-ubi9:1
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Esta es una mala práctica porque:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Es mutable, puede apuntar a otro build&lt;/li&gt;
&lt;li&gt;También es un error confiar ciegamente usar &lt;em&gt;latest&lt;/em&gt;, hoy puede apuntar a una versión, mañana a otra&lt;/li&gt;
&lt;li&gt;Dificulta el debugging al no saber exactamente qué versión usás&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;✅ Buena práctica:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;podman&lt;span class="w"&gt; &lt;/span&gt;run&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;--name&lt;span class="w"&gt; &lt;/span&gt;pass-git&lt;span class="w"&gt; &lt;/span&gt;--pull&lt;span class="o"&gt;=&lt;/span&gt;never&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;localhost/passteiner-ubi9@sha256:3ca1e63acb24d88fde5e86eb1f476ba69eb740cd43590c37f3a964b5a19f001
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Ventajas:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Totalmente reproducible y auditable.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Evitás actualizaciones sorpresa.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ideal para ambientes de producción, CI/CD, y entornos donde la confiabilidad importa.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="power-tip-2-examinar-vulnerabilidades-en-imagenes-de-contenedores"&gt;Power Tip #2 Examinar vulnerabilidades en imágenes de contenedores&lt;/h3&gt;
&lt;p&gt;La abstración con que nos proporcionan los contenedores, tal vez nos den una falsa sensación de seguridad, sin embargo, con trivy se pueden escanear en una imagen vulnerabilades por ejemplo:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;trivy&lt;span class="w"&gt; &lt;/span&gt;image&lt;span class="w"&gt; &lt;/span&gt;docker.io/bitnami/wordpress
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Debajo podemos ver un resumen:&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/pt5-trivy.webp"&gt;&lt;img src="https://sergiobelkin.com/images/pt5-trivy.thumbnail.webp" alt="Resumen del reporte realizado por trivy"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h3 id="power-tip-3-examinar-imagenes-de-contenedores-sin-necesidad-pullearlas"&gt;Power Tip #3 Examinar imágenes de contenedores sin necesidad "pullearlas"&lt;/h3&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;skopeo&lt;span class="w"&gt; &lt;/span&gt;inspect&lt;span class="w"&gt; &lt;/span&gt;docker://docker.io/ollama/ollama&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;jq&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{Digest: .Digest, Labels: .Labels, UltimaCapa: .Layers[-1]}'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"Digest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sha256:a5409cb903d30f9cd67e9f430dd336ddc9274e16fd78f75b675c42065991b4fd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"Labels"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"org.opencontainers.image.ref.name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ubuntu"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"org.opencontainers.image.version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"24.04"&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"UltimaCapa"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sha256:45fafbfc0e267e3b61858ae5cb28ff739d901d85e1b60ee62db5dad64ae7c0d5"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id="de-esta-manera-obtenemos"&gt;De esta manera obtenemos:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;El &lt;strong&gt;Digest&lt;/strong&gt; de la imagen (identificador único inmutable).&lt;/li&gt;
&lt;li&gt;En qué &lt;strong&gt;distro base y versión&lt;/strong&gt; se construyó la imagen (&lt;code&gt;ubuntu:24.04&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;El &lt;strong&gt;Digest de la última capa&lt;/strong&gt;, que representa el &lt;strong&gt;último cambio&lt;/strong&gt; al sistema de archivos durante el proceso de build.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;El digest de la última capa representa el último cambio al sistema de archivos en el proceso de construcción de la imagen.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="power-link"&gt;Power Link&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://codesmash.dev/why-i-ditched-docker-for-podman-and-you-should-too"&gt;Why I Ditched Docker for Podman And You Should Too&lt;/a&gt;&lt;/p&gt;</description><category>bash</category><guid>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i5/</guid><pubDate>Sat, 13 Sep 2025 19:38:48 GMT</pubDate></item><item><title>3 Power Tips + 1 Power Link I4</title><link>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i4/</link><dc:creator>sebelk</dc:creator><description>&lt;figure&gt;&lt;img src="https://sergiobelkin.com/images/PowerTipsPlus.png"&gt;&lt;/figure&gt; &lt;p&gt;Resumen: Tips para &lt;strong&gt;curl&lt;/strong&gt;, &lt;strong&gt;ollama&lt;/strong&gt; y &lt;strong&gt;KDE Plasma&lt;/strong&gt;. Y un link acerca de cómo las organizaciones están usando el open source y el upskilling para responder a las demandas laborales impulsadas por IA&lt;/p&gt;
&lt;h3 id="power-tip-1"&gt;Power Tip #1&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Obtener un json con información de diagnóstico a partir de curl&lt;/strong&gt;. Por ejemplo: una solicitud que devuelva el &lt;em&gt;código de respuesta http&lt;/em&gt;, &lt;em&gt;la versión del protocolo http`, &lt;/em&gt;la dirección ip&lt;em&gt;, &lt;/em&gt;el tiempo de transferencia hasta el primer byte recibido&lt;em&gt; y el &lt;/em&gt;tiempo total de la operación completa*:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-Ls&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;/dev/null&lt;span class="w"&gt; &lt;/span&gt;-w&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{"code":%{response_code},"http":"%{http_version}","ip":"%{remote_ip}","ttfb":%{time_starttransfer},"total":%{time_total}}\n'&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;https://fast.com&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;jq
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/pt1-curl-json.webp"&gt;&lt;img src="https://sergiobelkin.com/images/pt1-curl-json.thumbnail.webp" alt="Ejemplo de curl obteniendo json con información de diagnóstico"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h3 id="power-tip-2"&gt;Power Tip #2&lt;/h3&gt;
&lt;p&gt;En &lt;a href="https://sergiobelkin.com/posts/3-power-tips-plus-1-power-link-i3/"&gt;el PT 2 anterior&lt;/a&gt; mostramos como usar un LLM offline. Aquí tenemos un &lt;strong&gt;script para bajar e instalar ollama&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="ch"&gt;#! /usr/bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/tmp&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
curl&lt;span class="w"&gt; &lt;/span&gt;-LO&lt;span class="w"&gt; &lt;/span&gt;https://ollama.com/download/ollama-linux-amd64.tgz
sudo&lt;span class="w"&gt; &lt;/span&gt;tar&lt;span class="w"&gt; &lt;/span&gt;-C&lt;span class="w"&gt; &lt;/span&gt;/usr/local&lt;span class="w"&gt; &lt;/span&gt;-xzf&lt;span class="w"&gt; &lt;/span&gt;ollama-linux-amd64.tgz
sudo&lt;span class="w"&gt; &lt;/span&gt;useradd&lt;span class="w"&gt; &lt;/span&gt;-r&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;/bin/false&lt;span class="w"&gt; &lt;/span&gt;-U&lt;span class="w"&gt; &lt;/span&gt;-m&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;/usr/local/share/ollama&lt;span class="w"&gt; &lt;/span&gt;ollama
sudo&lt;span class="w"&gt; &lt;/span&gt;usermod&lt;span class="w"&gt; &lt;/span&gt;-a&lt;span class="w"&gt; &lt;/span&gt;-G&lt;span class="w"&gt; &lt;/span&gt;ollama&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;whoami&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
sudo&lt;span class="w"&gt; &lt;/span&gt;tee&lt;span class="w"&gt;  &lt;/span&gt;/etc/systemd/system/ollama.service&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;lt;&amp;lt; 'EOF'&lt;/span&gt;
&lt;span class="s"&gt;[Unit]&lt;/span&gt;
&lt;span class="s"&gt;Description=Ollama Service&lt;/span&gt;
&lt;span class="s"&gt;After=network-online.target&lt;/span&gt;

&lt;span class="s"&gt;[Service]&lt;/span&gt;
&lt;span class="s"&gt;ExecStart=/usr/local/bin/ollama serve&lt;/span&gt;
&lt;span class="s"&gt;User=ollama&lt;/span&gt;
&lt;span class="s"&gt;Group=ollama&lt;/span&gt;
&lt;span class="s"&gt;Restart=always&lt;/span&gt;
&lt;span class="s"&gt;RestartSec=3&lt;/span&gt;
&lt;span class="s"&gt;Environment="PATH=$PATH&lt;/span&gt;

&lt;span class="s"&gt;[Install]&lt;/span&gt;
&lt;span class="s"&gt;WantedBy=multi-user.target&lt;/span&gt;
&lt;span class="s"&gt;EOF&lt;/span&gt;

sudo&lt;span class="w"&gt; &lt;/span&gt;systemctl&lt;span class="w"&gt; &lt;/span&gt;daemon-reload
sudo&lt;span class="w"&gt; &lt;/span&gt;systemctl&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;enable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--now&lt;span class="w"&gt; &lt;/span&gt;ollama
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Y ya está listo &lt;strong&gt;ollama&lt;/strong&gt; para usar. 😉 &lt;/p&gt;
&lt;h3 id="power-tip-3"&gt;Power Tip #3&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Configurar klipper en Plasma para que al copiar una url llame a una acción&lt;/strong&gt;. A diferencia de lo que ocurre en otros entornos o sistemas operativos, el &lt;strong&gt;Portapapeles&lt;/strong&gt; de Plasma no sirve solamente para cortar/copiar y pegar. Sino que puede realizar tareas que hacen más sencillas las tareas tanto para usuarios finales como para usuarios administradores y/o desarrolladores.
Los fundamentos de este &lt;strong&gt;Power Tip&lt;/strong&gt; son:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Una &lt;strong&gt;expresión regular&lt;/strong&gt;, por ejemplo: &lt;code&gt;^(https?://[^ \t\r\n"'&amp;lt;&amp;gt;]+)$&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Una &lt;strong&gt;acción comando&lt;/strong&gt;, por ejemplo: &lt;code&gt;konsole --new-tab -e bash -lc 'curl -I -L -- "%1"; exec "${SHELL:-/bin/bash}" -i'&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Dentro de la &lt;strong&gt;configuración del Portapapeles (&lt;em&gt;klipper&lt;/em&gt;)&lt;/strong&gt;, se pueden realizar esos y otros ajustes.&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/pt3-klipper-acttion-config.webp"&gt;&lt;img src="https://sergiobelkin.com/images/pt3-klipper-acttion-config.thumbnail.webp" alt="Configurar una acción en Klipper"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Luego al copiar una URL, podemos usar un menú emergente que dispare la acción &lt;strong&gt;(en este de acuerdo al ejemplo arriba mencionado el comando curl en konsole)&lt;/strong&gt;.  💪 &lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/pt3-klipper-acttion-example.webp"&gt;&lt;img src="https://sergiobelkin.com/images/pt3-klipper-acttion-example.thumbnail.webp" alt="Configurar una acción en Klipper"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h3 id="power-link"&gt;Power Link&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://training.linuxfoundation.org/blog/just-released-2025-state-of-tech-talent-report/"&gt;2025 State of Tech Talent Report&lt;/a&gt;&lt;/p&gt;</description><category>bash</category><guid>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i4/</guid><pubDate>Mon, 11 Aug 2025 22:20:56 GMT</pubDate></item><item><title>3 Power Tips + 1 Power Link I3</title><link>https://sergiobelkin.com/posts/3-power-tips-plus-1-power-link-i3/</link><dc:creator>sebelk</dc:creator><description>&lt;figure&gt;&lt;img src="https://sergiobelkin.com/images/PowerTipsPlus.png"&gt;&lt;/figure&gt; &lt;p&gt;En esta edición, tips para &lt;strong&gt;bash scripting&lt;/strong&gt;, gestión de paquetes con &lt;strong&gt;dnf&lt;/strong&gt;, y &lt;strong&gt;LLM en tu máquina&lt;/strong&gt;.  😉 
Y un link sobre como se refieren los medios de comunicación a la IA.&lt;/p&gt;
&lt;h3 id="power-tip-1"&gt;Power Tip #1&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Self-logging script con exec&lt;/strong&gt; (script con logging incorporado)&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="ch"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nv"&gt;LOG_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/logs"&lt;/span&gt;
mkdir&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LOG_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;LOG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LOG_DIR&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;basename&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;_&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;date&lt;span class="w"&gt; &lt;/span&gt;+%Y%m%d-%H%M%S&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;_&lt;/span&gt;&lt;span class="nv"&gt;$$&lt;/span&gt;&lt;span class="s2"&gt;.log"&lt;/span&gt;
&lt;span class="nb"&gt;exec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="o"&gt;(&lt;/span&gt;tee&lt;span class="w"&gt; &lt;/span&gt;-a&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LOG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
ping&lt;span class="w"&gt; &lt;/span&gt;-c10&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;9&lt;/span&gt;.9.9.9
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;La línea &lt;code&gt;exec &amp;gt; &amp;gt;(tee -a "$LOG") 2&amp;gt;&amp;amp;1&lt;/code&gt; sirve para que &lt;strong&gt;toda&lt;/strong&gt; la salida del script también vaya el archivo determinado por la variable &lt;code&gt;$LOG&lt;/code&gt;.
&lt;strong&gt;Comentario&lt;/strong&gt;: En general &lt;code&gt;2&amp;gt;&amp;amp;1&lt;/code&gt; es reemplazado por &lt;code&gt;&amp;amp;&amp;gt;&lt;/code&gt;,  en versiones de bash bastante recientes. ¿Y por qué no usarlo? Porque ese atajo solamente sirve para redireccionar a archivos regulares. Por lo tanto, hay que usar la manera clásica de redireccionamiento de &lt;strong&gt;stdin&lt;/strong&gt; y &lt;strong&gt;stderr&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id="power-tip-2"&gt;Power Tip #2&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Reemplazar un paquete por otro con dnf&lt;/strong&gt;. Por ejemplo, reemplazar pipewire-pulseaudio, por pulseaudio, en caso de problemas de compatibilidad.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;dnf&lt;span class="w"&gt; &lt;/span&gt;swap&lt;span class="w"&gt; &lt;/span&gt;pipewire-pulseaudio&lt;span class="w"&gt; &lt;/span&gt;pulseaudio&lt;span class="w"&gt; &lt;/span&gt;--allowerasing
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="power-tip-3"&gt;Power Tip #3&lt;/h3&gt;
&lt;p&gt;Usar ollama, para ejecutar y gestionar modelos de AI especializados en lenguaje  en tu propia máquina, por ejemplo para explicar el contenido de un archivo:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;ollama&lt;span class="w"&gt; &lt;/span&gt;run&lt;span class="w"&gt; &lt;/span&gt;gemma3&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Explicar sintéticamente, lo que hace este archivo de reglas de polkit  &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;cat&lt;span class="w"&gt; &lt;/span&gt;/usr/share/polkit-1/rules.d/org.freedesktop.Flatpak.rules&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/ollama.webp"&gt;&lt;img src="https://sergiobelkin.com/images/ollama.thumbnail.webp" alt="Ollama, LLM en tu propia máquina"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h3 id="power-link"&gt;Power Link&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.readtpa.com/p/stop-pretending-chatbots-have-feelings"&gt;Stop Pretending Chatbots Have Feelings: Media's Dangerous AI Anthropomorphism Problem&lt;/a&gt;&lt;/p&gt;</description><category>bash</category><guid>https://sergiobelkin.com/posts/3-power-tips-plus-1-power-link-i3/</guid><pubDate>Tue, 29 Jul 2025 22:27:32 GMT</pubDate></item><item><title>3 Power Tips + 1 Power Link I2</title><link>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i2/</link><dc:creator>sebelk</dc:creator><description>&lt;figure&gt;&lt;img src="https://sergiobelkin.com/images/PowerTipsPlus.png"&gt;&lt;/figure&gt; &lt;p&gt;&lt;strong&gt;En esta edición: 3 poderosos consejos para bash, advirtiéndo sobre la letra chica de ellas y una noticia importante sobre certificados SSL/TLS.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="power-tip-1"&gt;Power Tip #1&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Agregar de manera inteligente y selectiva la opción pipefail en bash con &lt;code&gt;set -o pipefail&lt;/code&gt; a los scripts de bash.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;De esta manera, bastará con que un solo comando tenga un estado de salida distinto de &lt;code&gt;0&lt;/code&gt; para que el resultado final también de distinto de &lt;code&gt;0&lt;/code&gt;. Hay muchas publicaciones e incluso GPTs que aconsejan el uso de &lt;code&gt;pipefail&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;Esto puede ser valioso cuando cualquier comando unido por &lt;code&gt;|&lt;/code&gt; tiene que terminar sin errores para que tenga sentido continuar con la ejecución del script.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sin embargo, acá van algunas recomendaciones:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Evitar &lt;code&gt;set -o pipefail&lt;/code&gt; globalmente al usar comandos como:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;grep -q&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;head&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;awk 'exit'&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sed 'q'&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Activar &lt;code&gt;pipefail&lt;/code&gt; solo donde realmente sea necesaria:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;pipefail&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;comando1&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;comando2&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;O desactivar luego de usarla:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;pipefail
comando1&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;comando2
&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;+o&lt;span class="w"&gt; &lt;/span&gt;pipefail
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="power-tip-2"&gt;Power Tip #2&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Realizá tus propios tests para decidir si un script tiene que terminar al ocurrir un error&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Se puede leer en el &lt;a href="https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html#writing-maintainer-scripts"&gt;Debian Policy Manual&lt;/a&gt; que recomienda fuertemente  el uso  &lt;code&gt;set -e&lt;/code&gt;. Esa opción le dice a bash que cuando un comando termina en un estado de salida de distinto de &lt;code&gt;0&lt;/code&gt; el script debe termina inmediatamente. La cuestión es que esa opción tiene muchas de excepciones (&lt;em&gt;algo que se puede verificar al leer la manpage de bash&lt;/em&gt;), lo cual hace el uso de esta configuración poco confiable en scripts de gran complejidad.
Tenemos que comprender que bash sabe poco de la semántica. Por ejemplo, considerar este sencillo script:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="ch"&gt;#! /bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-e

&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/home/admin/download
curl&lt;span class="w"&gt; &lt;/span&gt;-O&lt;span class="w"&gt; &lt;/span&gt;https://example.com/project.zip
unzip&lt;span class="w"&gt; &lt;/span&gt;project.zip
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;El comando curl no tiene &lt;strong&gt;exit status distinto de 0&lt;/strong&gt; si obtiene http code 404, &lt;strong&gt;bash no sabe como cada herramienta externa maneja el exit status&lt;/strong&gt;. Si el archivo projec.zip ya existe, el comando unzip estará operando sobre el la versión del archivo que probablemente no queremos.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lo correcto que nosotros mismos le agreguemos la lógica necesaria de acuerdo a lo que estamos necesitando&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Probablemente alguien puede estar tentado a agregarle la opción &lt;code&gt;-f&lt;/code&gt; sin embargo la propia manpage de &lt;code&gt;curl&lt;/code&gt; dice que no es 100% segura. Además puede haber casos en los que necesitamos saber exactamente el tipo de problema que hubo. En tal caso lo mejor será obtener el http code con curl y evaluar dicho código con bash, es decir hacemos que &lt;strong&gt;cada herramienta haga lo mejor que sabe hacer&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id="power-tip-3"&gt;Power Tip #3&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Usar &lt;code&gt;set -u&lt;/code&gt; para forzar a que el script termine con error si hay hay variables no definidas&lt;/strong&gt;. En general, esta opción tiene menos tiene contraindicaciones que las dos anteriores. &lt;strong&gt;Es altamente conveniente combinarla con la herramienta &lt;code&gt;shellcheck&lt;/code&gt;&lt;/strong&gt;. Por ejemplo, en el siguiente script:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="ch"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-u
&lt;span class="o"&gt;[[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DEBUG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"yes"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Modo debug"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$somevar&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;someanothervar&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"example"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;No tiene definida la variable &lt;code&gt;DEBUG&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;No tiene definida la variable &lt;code&gt;somevar&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;La variable &lt;code&gt;someanothervar&lt;/code&gt; si bien está definida no se usa nunca. No es un error grave, pero al no utilizarse probablemente sea inncesaria, pero es algo que no es detectado por &lt;code&gt;set -u&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/shellcheck.webp"&gt;&lt;img src="https://sergiobelkin.com/images/shellcheck.thumbnail.webp" alt="ShellCheck"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h3 id="power-link"&gt;Power Link&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;¿Certificados SSL/TLS para direcciones IP?&lt;/strong&gt;:
&lt;a href="https://letsencrypt.org/2025/07/01/issuing-our-first-ip-address-certificate/"&gt;We've Issued Our First IP Address Certificate&lt;/a&gt;&lt;/p&gt;</description><category>bash</category><guid>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i2/</guid><pubDate>Sat, 05 Jul 2025 19:57:16 GMT</pubDate></item><item><title>3 Power Tips + 1 Power Link I1</title><link>https://sergiobelkin.com/posts/3-power-tips-plus-i1/</link><dc:creator>sebelk</dc:creator><description>&lt;figure&gt;&lt;img src="https://sergiobelkin.com/images/PowerTipsPlus.webp"&gt;&lt;/figure&gt; &lt;h3 id="power-tip-1"&gt;Power Tip #1&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;El comando &lt;code&gt;cd -&lt;/code&gt; sirve para ir rápidamente al directorio anterior&lt;/strong&gt;&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/usr/local/bin
&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/tmp
&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-
&lt;span class="nb"&gt;pwd&lt;/span&gt;
/usr/local/bin
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="power-tip-2"&gt;Power Tip #2&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;La variable &lt;code&gt;HISTTIMEFORMAT&lt;/code&gt; agrega una marca de tiempo en el hi:storial de bash&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Agegar en &lt;code&gt;~/.bashrc&lt;/code&gt;&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nv"&gt;HISTTIMEFORMAT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"%F %T"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;También se puede usar &lt;a href="https://sergiobelkin.com/posts/frameworks-para-bash-realmente-los-necesitamos-una-mirada-profunda-a-bash-it/"&gt;bash-it&lt;/a&gt; para realizar la configuración.&lt;/p&gt;
&lt;p&gt;Al recargar la configuración, se agregará la marca de tiempo:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="m"&gt;234475&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;2025&lt;/span&gt;-06-03&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;21&lt;/span&gt;:54:27&lt;span class="w"&gt; &lt;/span&gt;vim&lt;span class="w"&gt;  &lt;/span&gt;~/Documentos/Arts/nikola-env/sebelkfloss/files/assets/css/custom.css&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="m"&gt;234476&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;2025&lt;/span&gt;-06-02&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;08&lt;/span&gt;:18:37&lt;span class="w"&gt; &lt;/span&gt;vim&lt;span class="w"&gt;  &lt;/span&gt;~/.config/nvim/lua/core/lazy.lua&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="m"&gt;234477&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;2025&lt;/span&gt;-06-04&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;18&lt;/span&gt;:27:09&lt;span class="w"&gt; &lt;/span&gt;nohup&lt;span class="w"&gt; &lt;/span&gt;nikola&lt;span class="w"&gt; &lt;/span&gt;serve&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;/dev/null&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;
&lt;span class="m"&gt;234478&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;2025&lt;/span&gt;-06-04&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;18&lt;/span&gt;:29:38&lt;span class="w"&gt; &lt;/span&gt;vim&lt;span class="w"&gt;  &lt;/span&gt;~/.config/nvim/lua/core/lazy.lua&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="m"&gt;234479&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;2025&lt;/span&gt;-06-04&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;18&lt;/span&gt;:29:57&lt;span class="w"&gt; &lt;/span&gt;loadnikola&lt;span class="w"&gt; &lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="power-tip-3"&gt;Power Tip #3&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Usar una herramienta de monitoreo local como wallpaper&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;El emulador de terminal &lt;code&gt;kitty&lt;/code&gt; posee herramientas pequeñas que amplian su funcionalidad. Una de ellas permite mostrar usar la terminal como wallpaper:&lt;/p&gt;
&lt;p&gt;Este comando mostrará el panel de la herramienta &lt;code&gt;glances&lt;/code&gt; en un entorno Wayland&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;kitty&lt;span class="w"&gt; &lt;/span&gt;+kitten&lt;span class="w"&gt; &lt;/span&gt;panel&lt;span class="w"&gt; &lt;/span&gt;--edge&lt;span class="o"&gt;=&lt;/span&gt;background&lt;span class="w"&gt; &lt;/span&gt;--focus-policy&lt;span class="w"&gt; &lt;/span&gt;exclusive&lt;span class="w"&gt; &lt;/span&gt;--detach&lt;span class="w"&gt;  &lt;/span&gt;glances
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;

&lt;/p&gt;&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
  &lt;iframe src="https://www.youtube.com/embed/8QzpwiyLw2o?vq=hd720" frameborder="0" allowfullscreen style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;


&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;h3 id="power-link"&gt;Power Link&lt;/h3&gt;
&lt;p&gt;Sencillamente un link: &lt;a href="https://stopdisablingselinux.com/"&gt;Stop disabling SELinux&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;¡Hasta la próxima!&lt;/strong&gt;&lt;/p&gt;</description><category>bash</category><category>seguridad</category><guid>https://sergiobelkin.com/posts/3-power-tips-plus-i1/</guid><pubDate>Tue, 17 Jun 2025 19:25:26 GMT</pubDate></item></channel></rss>