<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>alchemmist — Linux</title><link>https://alchemmist.xyz/ru/tags/linux/</link><description>Последние записи в блоге alchemmist</description><generator>Hugo 0.163.3</generator><language>ru</language><atom:link href="https://alchemmist.xyz/ru/tags/linux/index.xml" rel="self" type="application/rss+xml"/><lastBuildDate>Sat, 23 Aug 2025 17:14:00 +0300</lastBuildDate><item><title>Безопасно делимся экраном в Hyprland</title><link>https://alchemmist.xyz/ru/articles/hyrpland-noscreenshare/</link><pubDate>Sat, 23 Aug 2025 17:14:00 +0300</pubDate><dc:creator>alchemmist</dc:creator><guid>https://alchemmist.xyz/ru/articles/hyrpland-noscreenshare/</guid><description>Мы все были в ситуации, когда нужно показать экран с множеством окон, и требуется несколько минут перед нажатием кнопки “Поделиться экраном”, чтобы принять решение. Это нормально, особенно если ваша система — ваш второй (или даже первый) дом: с личными заметками, документами, паролями, чатами и так далее.
Далее мы настроим удобный рабочий процесс для такого случая. Однако эта настройка будет использовать новую функцию, встроенную в Hyprland и, скорее всего, отсутствующую в других DE/композиторах. Я продемонстрирую нашу конечную цель. Например, мой режим демонстрации экрана может выглядеть так:</description><content:encoded><![CDATA[<p>Мы все были в ситуации, когда нужно показать экран с множеством окон, и требуется несколько минут перед нажатием кнопки &ldquo;Поделиться экраном&rdquo;, чтобы принять решение. Это нормально, особенно если ваша система — ваш второй (или даже первый) дом: с личными заметками, документами, паролями, чатами и так далее.</p>
<p>Далее мы настроим удобный рабочий процесс для такого случая. Однако эта настройка будет использовать новую функцию, встроенную в Hyprland и, скорее всего, отсутствующую в других DE/композиторах. Я продемонстрирую нашу конечную цель. Например, мой режим демонстрации экрана может выглядеть так:
<img src="/images/noscreenshare-demo.mp4" class="content-img" style="width:85px" alt="" loading="lazy" decoding="async" /></p>
<blockquote class="markdown-blockquote">
  <p>Если вам нравятся мои обои, вы можете найти <a href="https://github.com/alchemmist/dotfiles/blob/main/wallpapers/miyazaki/images/1198594-3200x1680-desktop-hd-studio-ghibli-background.jpg">эти</a> и много других отличных материалов в моём репозитории <code>dotfiles</code> на <a href="https://github.com/alchemmist/dotfiles/tree/main/wallpapers">GitHub</a>. Не забывайте: я обожаю ваши звёзды!</p>

</blockquote>
<p>Разберём всё по шагам. Во-первых, вспомним, что в <a href="https://hypr.land/news/update50/#:~:text=on%20by%20default.-,No%20screen%20share,-There%E2%80%99s%20a%20new">релизе</a> Hyprland версии <code>0.50.0</code> было добавлено новое правило <code>windowrulev2</code> с опцией <code>noscreenshare</code>. Это свежий релиз, и сейчас оно управляется только из конфигурационного файла, вот так:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-plaintext" data-lang="plaintext"><span class="line"><span class="cl">windowrulev2 = noscreenshare, class:^(org.telegram.desktop|obsidian|discord)$
</span></span></code></pre></div><p>Эта опция предписывает Hyprland рисовать чёрный прямоугольник вместо содержимого окна (даже если это окно не в фокусе или на заднем плане). Это работает идеально и защищает нашу приватность. Но я обнаружил два неудобных случая: 1. Когда мы хотим сделать скриншот (в моём случае, с помощью flameshot), Hyprland интерпретирует это как попытку поделиться экраном и скрывает все приватные окна. 2. Иногда я хочу показать что-то из моего Obsidian, например, и лезть в конфиги в этот момент — не очень хорошо.</p>

<h2 id="управление-опцией-noscreenshare-через-cli">
  <a class="link" href="#%d1%83%d0%bf%d1%80%d0%b0%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5-%d0%be%d0%bf%d1%86%d0%b8%d0%b5%d0%b9-noscreenshare-%d1%87%d0%b5%d1%80%d0%b5%d0%b7-cli">
    #
  </a>
  Управление опцией noscreenshare через CLI
</h2>

<p>Чтобы исправить этот опыт, напишем скрипт для управления правилом окна в конфиге. Если у вас нет времени, полная версия скрипта здесь. Скрипт будет комментировать или раскомментировать строку в конфигурационном файле с правилом и сохранять информацию о текущем состоянии правила в файле-маркере <code>~/.config/hypr/.screenshare_rule_disabled</code>. Скрипт можно запустить с командой <code>toggle</code>, чтобы изменить состояние на противоположное:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">CONFIG_FILE</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.config/hypr/hyprland.conf&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">STATE_FILE</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.config/hypr/.screenshare_rule_disabled&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">toggle_rule<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">	<span class="c1"># TODO</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">case</span> <span class="si">${</span><span class="nv">1</span><span class="si">}</span> in
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;toggle&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">        toggle_rule
</span></span><span class="line"><span class="cl">        <span class="p">;;</span>
</span></span><span class="line"><span class="cl"><span class="k">esac</span>
</span></span></code></pre></div><p>Напишем функцию <code>toggle_rule</code>. Мы будем использовать утилиту Linux <code>sed</code> (<em>Stream Editor</em>). Это один из самых мощных инструментов для обработки текста в Linux и Unix-системах. Он обычно используется для таких задач, как поиск и замена, преобразование текста и потоковое редактирование. Синтаксис <code>sed</code>, в общем виде, выглядит так:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sed <span class="o">[</span>options<span class="o">]</span> <span class="s2">&#34;script&#34;</span> <span class="o">[</span>file...<span class="o">]</span>
</span></span></code></pre></div><p>Нам нужна опция <code>-i</code> для редактирования файла на месте. Затем пишем скрипт. Сначала нам нужно найти строку с правилом <code>noscreenshare</code>, как в regex:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="s2">&#34;/windowrolev2.*noscreenshare.*&#34;</span>
</span></span></code></pre></div><p>Мы начинаем с <code>&quot;/&quot;</code> для написания поискового запроса, нам нужно, чтобы строка начиналась с <code>&quot;windowrolev2&quot;</code>, после чего <code>&quot;.*&quot;</code> для любого количества любых символов, между которыми <code>&quot;noscreenshare&quot;</code>. Затем мы используем <code>&quot;/&quot;</code> для завершения поискового запроса и <code>&quot;s/&quot;</code> (<em>substitute</em>) для замены:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="s2">&#34;/windowrulev2.*noscreenshare.*/s/^#//&#34;</span>
</span></span></code></pre></div><p>Наконец, мы используем регулярное выражение <code>&quot;^#&quot;</code> для поиска решётки в начале строки и заменяем её на ничто: <code>&quot;//&quot;</code>. Полная команда выглядит так:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sed -i <span class="s1">&#39;/windowrulev2.*noscreenshare.*/s/^#//&#39;</span> <span class="s2">&#34;</span><span class="nv">$CONFIG_FILE</span><span class="s2">&#34;</span>
</span></span></code></pre></div><p>Затем используем <code>sed</code> для добавления решётки в начало строки аналогичным образом, в зависимости от наличия файла-маркера:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">toggle_rule<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="o">[</span> -f <span class="s2">&#34;</span><span class="nv">$STATE_FILE</span><span class="s2">&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">        sed -i <span class="s1">&#39;/windowrulev2.*noscreenshare.*/s/^#//&#39;</span> <span class="s2">&#34;</span><span class="nv">$CONFIG_FILE</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        rm -f <span class="s2">&#34;</span><span class="nv">$STATE_FILE</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">CLASS</span><span class="o">=</span><span class="s2">&#34;on&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span>
</span></span><span class="line"><span class="cl">        sed -i <span class="s1">&#39;/windowrulev2.*noscreenshare.*/s/^/#/&#39;</span> <span class="s2">&#34;</span><span class="nv">$CONFIG_FILE</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        touch <span class="s2">&#34;</span><span class="nv">$STATE_FILE</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">CLASS</span><span class="o">=</span><span class="s2">&#34;of&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">fi</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span></code></pre></div><p>На последнем шаге скрипта мы вызываем эту функцию, если была дана опция <code>toggle</code>, и возвращаем json-подобную строку для waybar. Полный скрипт:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">CONFIG_FILE</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.config/hypr/hyprland.conf&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">STATE_FILE</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.config/hypr/.screenshare_rule_disabled&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">toggle_rule<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="o">[</span> -f <span class="s2">&#34;</span><span class="nv">$STATE_FILE</span><span class="s2">&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">        sed -i <span class="s1">&#39;/windowrulev2.*noscreenshare.*/s/^#//&#39;</span> <span class="s2">&#34;</span><span class="nv">$CONFIG_FILE</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        rm -f <span class="s2">&#34;</span><span class="nv">$STATE_FILE</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">CLASS</span><span class="o">=</span><span class="s2">&#34;on&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span>
</span></span><span class="line"><span class="cl">        sed -i <span class="s1">&#39;/windowrulev2.*noscreenshare.*/s/^/#/&#39;</span> <span class="s2">&#34;</span><span class="nv">$CONFIG_FILE</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        touch <span class="s2">&#34;</span><span class="nv">$STATE_FILE</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">CLASS</span><span class="o">=</span><span class="s2">&#34;off&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">fi</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">case</span> <span class="si">${</span><span class="nv">1</span><span class="si">}</span> in
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;toggle&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">        toggle_rule
</span></span><span class="line"><span class="cl">        <span class="p">;;</span>
</span></span><span class="line"><span class="cl">    *<span class="o">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="o">[</span> -f <span class="s2">&#34;</span><span class="nv">$STATE_FILE</span><span class="s2">&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">            <span class="nv">CLASS</span><span class="o">=</span><span class="s2">&#34;off&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="k">else</span>
</span></span><span class="line"><span class="cl">            <span class="nv">CLASS</span><span class="o">=</span><span class="s2">&#34;on&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="k">fi</span>
</span></span><span class="line"><span class="cl">        <span class="p">;;</span>
</span></span><span class="line"><span class="cl"><span class="k">esac</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;{\&#34;class\&#34;: \&#34;</span><span class="nv">$CLASS</span><span class="s2">\&#34;, \&#34;alt\&#34;: \&#34;</span><span class="nv">$CLASS</span><span class="s2">\&#34;}&#34;</span>
</span></span></code></pre></div>
<h2 id="модуль-waybar">
  <a class="link" href="#%d0%bc%d0%be%d0%b4%d1%83%d0%bb%d1%8c-waybar">
    #
  </a>
  Модуль Waybar
</h2>

<p>Чтобы использовать это удобно и мгновенно определять текущее состояние приватности, напишем модуль waybar:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="s2">&#34;custom/noscreenshare&#34;</span><span class="err">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;exec&#34;</span><span class="p">:</span> <span class="s2">&#34;~/scripts/toggle_noscreenshare.sh&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;on-click&#34;</span><span class="p">:</span> <span class="s2">&#34;~/scripts/toggle_noscreenshare.sh toggle &amp;&amp; pkill -SIGRTMIN+4 waybar&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;signal&#34;</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;interval&#34;</span><span class="p">:</span> <span class="s2">&#34;once&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;return-type&#34;</span><span class="p">:</span> <span class="s2">&#34;json&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;format&#34;</span><span class="p">:</span> <span class="s2">&#34;{icon}&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;format-icons&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;off&#34;</span><span class="p">:</span> <span class="s2">&#34;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;on&#34;</span><span class="p">:</span> <span class="s2">&#34;󰗹&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;tooltip&#34;</span><span class="p">:</span> <span class="kc">false</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span><span class="err">,</span>
</span></span></code></pre></div><p>Опишем, что здесь происходит. Чтобы получить значение для этого модуля, мы используем поле <code>exec</code> и указываем наш скрипт. Затем мы определяем, что произойдёт при клике на модуль в опции <code>on-click</code>: запуск скрипта с опцией <code>toggle</code> и отправка системного сигнала waybar. Это позволяет не перезагружать весь процесс waybar, а только этот модуль. Здесь очень важно синхронизировать значение <code>signal</code> и число в команде <code>pkill -SIGRTMIN+4 waybar</code>, и сделать это значение уникальным только для этого модуля waybar. Затем мы настраиваем однократный запуск нашего скрипта при старте waybar и определяем формат отображения (<code>tooltip: false</code> для отключения текста при наведении курсора). Я использую эти иконки nerdfonts для этого, но они не одинакового размера. Поэтому я тонко настраиваю отступы и добавляю некоторые стили:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="p">#</span><span class="nn">custom-noscreenshare</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">background</span><span class="p">:</span> <span class="mh">#1e1e2e</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">opacity</span><span class="p">:</span> <span class="mf">0.7</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">padding</span><span class="p">:</span> <span class="mi">0</span><span class="kt">px</span> <span class="mi">10</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">margin</span><span class="p">:</span> <span class="mi">5</span><span class="kt">px</span> <span class="mi">5</span><span class="kt">px</span> <span class="mi">3</span><span class="kt">px</span> <span class="mi">0</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">border</span><span class="p">:</span> <span class="mi">0</span><span class="kt">px</span> <span class="kc">solid</span> <span class="mh">#181825</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">border-radius</span><span class="p">:</span> <span class="mi">10</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">#</span><span class="nn">custom-noscreenshare</span><span class="p">.</span><span class="nc">on</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">font-size</span><span class="p">:</span> <span class="mi">18</span><span class="kt">px</span><span class="p">;</span> 
</span></span><span class="line"><span class="cl">  <span class="k">padding-right</span><span class="p">:</span> <span class="mi">14</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">#</span><span class="nn">custom-noscreenshare</span><span class="p">.</span><span class="nc">off</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">font-size</span><span class="p">:</span> <span class="mi">16</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">padding-right</span><span class="p">:</span> <span class="mi">16</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">padding-left</span><span class="p">:</span> <span class="mi">9</span><span class="kt">px</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>После этого мы получаем удобный интерфейс для практичного контроля нашей приватности:<br>
<img src="/images/noscreenshare-demo.gif" class="content-img" style="width:700px" alt="" loading="lazy" decoding="async" /></p>
]]></content:encoded><category>linux</category></item><item><title>Деградация батареи в Linux</title><link>https://alchemmist.xyz/ru/articles/battery-degradation/</link><pubDate>Fri, 11 Jul 2025 09:58:00 +0300</pubDate><dc:creator>alchemmist</dc:creator><guid>https://alchemmist.xyz/ru/articles/battery-degradation/</guid><description>Мы все знаем, что батарея не вечна. Это нормально — можно заменить изношенную батарею в сервисе и снова использовать устройство. Но очень полезно видеть текущее состояние батареи. В MacOS это стандартная функция, в Linux мы, конечно, можем сделать то же самое. Давайте разберёмся!
Сначала мы поймём, как найти нужное значение, а затем создадим красивый минималистичный модуль для waybar.
# Находим значение деградации батареи Сначала получим список всех устройств питания:</description><content:encoded><![CDATA[<p>Мы все знаем, что батарея не вечна. Это нормально — можно заменить изношенную батарею в сервисе и снова использовать устройство. Но очень полезно видеть текущее состояние батареи. В MacOS это стандартная функция, в Linux мы, конечно, можем сделать то же самое. Давайте разберёмся!</p>
<p>Сначала мы поймём, как найти нужное значение, а затем создадим красивый минималистичный модуль для waybar.</p>

<h2 id="находим-значение-деградации-батареи">
  <a class="link" href="#%d0%bd%d0%b0%d1%85%d0%be%d0%b4%d0%b8%d0%bc-%d0%b7%d0%bd%d0%b0%d1%87%d0%b5%d0%bd%d0%b8%d0%b5-%d0%b4%d0%b5%d0%b3%d1%80%d0%b0%d0%b4%d0%b0%d1%86%d0%b8%d0%b8-%d0%b1%d0%b0%d1%82%d0%b0%d1%80%d0%b5%d0%b8">
    #
  </a>
  Находим значение деградации батареи
</h2>

<p>Сначала получим список всех устройств питания:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">upower -e
</span></span></code></pre></div><p>Затем найдём батарею в этом списке:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">upower -e <span class="p">|</span> grep BAT
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># For example:</span>
</span></span><span class="line"><span class="cl"><span class="c1"># /org/freedesktop/UPower/devices/battery_BATT</span>
</span></span></code></pre></div><p>Затем получим детальную информацию об этом устройстве:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">upower -i <span class="k">$(</span>upower -e <span class="p">|</span> grep BAT<span class="k">)</span>
</span></span></code></pre></div><p>Мы получим что-то вроде этого:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-txt" data-lang="txt"><span class="line"><span class="cl">  native-path:          BATT
</span></span><span class="line"><span class="cl">  vendor:               DESAY
</span></span><span class="line"><span class="cl">  model:                BASE-BAT
</span></span><span class="line"><span class="cl">  serial:               1
</span></span><span class="line"><span class="cl">  power supply:         yes
</span></span><span class="line"><span class="cl">  updated:              Fri Jul 11 11:37:00 2025 (7 seconds ago)
</span></span><span class="line"><span class="cl">  has history:          yes
</span></span><span class="line"><span class="cl">  has statistics:       yes
</span></span><span class="line"><span class="cl">  battery
</span></span><span class="line"><span class="cl">    present:             yes
</span></span><span class="line"><span class="cl">    rechargeable:        yes
</span></span><span class="line"><span class="cl">    state:               charging
</span></span><span class="line"><span class="cl">    warning-level:       none
</span></span><span class="line"><span class="cl">    energy:              25.514 Wh
</span></span><span class="line"><span class="cl">    energy-empty:        0 Wh
</span></span><span class="line"><span class="cl">    energy-full:         47.5052 Wh
</span></span><span class="line"><span class="cl">    energy-full-design:  59.4247 Wh
</span></span><span class="line"><span class="cl">    energy-rate:         11.1573 W
</span></span><span class="line"><span class="cl">    voltage:             11.972 V
</span></span><span class="line"><span class="cl">    charge-cycles:       650
</span></span><span class="line"><span class="cl">    time to full:        2.0 hours
</span></span><span class="line"><span class="cl">    percentage:          53%
</span></span><span class="line"><span class="cl">    capacity:            79.9417%
</span></span><span class="line"><span class="cl">    technology:          lithium-ion
</span></span><span class="line"><span class="cl">    charge-start-threshold:        75%
</span></span><span class="line"><span class="cl">    charge-end-threshold:          80%
</span></span><span class="line"><span class="cl">    charge-threshold-supported:    yes
</span></span><span class="line"><span class="cl">    icon-name:          &#39;battery-good-charging-symbolic&#39;
</span></span><span class="line"><span class="cl">  History (charge):
</span></span><span class="line"><span class="cl">    1752222927	53.000	charging
</span></span><span class="line"><span class="cl">  History (rate):
</span></span><span class="line"><span class="cl">    1752223020	11.157	charging
</span></span><span class="line"><span class="cl">    1752222990	11.123	charging
</span></span><span class="line"><span class="cl">    1752222987	11.192	charging
</span></span><span class="line"><span class="cl">    1752222957	10.822	charging
</span></span><span class="line"><span class="cl">    1752222927	10.857	charging
</span></span></code></pre></div><p>Здесь много интересной информации, например количество циклов зарядки, время до полной зарядки и т.д. Сейчас нас интересуют два параметра:</p>
<ul>
<li><code>energy-full-design</code> — изначальный полный объём батареи</li>
<li><code>energy-full</code> — текущий объём батареи</li>
</ul>
<p>Разница между этими параметрами и есть деградация батареи:
</p>
$$
\text{Degradation} = \left(1 - \frac{E_{\text{full}}}{E_{\text{design}}}\right) \times 100\%
$$<p>
Теперь посчитаем этот показатель в процентах.</p>
<p>Сначала найдём эти параметры и разделим их:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">upower -i <span class="k">$(</span>upower -e <span class="p">|</span> grep BAT<span class="k">)</span> <span class="p">|</span> awk <span class="s1">&#39;\
</span></span></span><span class="line"><span class="cl"><span class="s1">	/energy-full:/ {ef=$2}\
</span></span></span><span class="line"><span class="cl"><span class="s1">	/energy-full-design:/ {efd=$2}\
</span></span></span><span class="line"><span class="cl"><span class="s1">	END {print ef/efd}&#39;</span>
</span></span></code></pre></div><p>Затем посчитаем процентное значение:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;(1 - </span><span class="k">$(</span>upower -i <span class="k">$(</span>upower -e <span class="p">|</span> grep BAT<span class="k">)</span> <span class="p">|</span> awk <span class="s1">&#39;\
</span></span></span><span class="line"><span class="cl"><span class="s1">        /energy-full:/ {ef=$2}\
</span></span></span><span class="line"><span class="cl"><span class="s1">        /energy-full-design:/ {efd=$2}\
</span></span></span><span class="line"><span class="cl"><span class="s1">        END {print ef/efd}&#39;</span><span class="k">)</span><span class="s2">) * 100 + 0.5&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">	<span class="p">|</span> bc
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Output example:</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 20.558200</span>
</span></span></code></pre></div><p>На последнем шаге нам нужно округлить значение:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;(1 - </span><span class="k">$(</span>upower -i <span class="k">$(</span>upower -e <span class="p">|</span> grep BAT<span class="k">)</span> <span class="p">|</span> awk <span class="s1">&#39;\
</span></span></span><span class="line"><span class="cl"><span class="s1">        /energy-full:/ {ef=$2}\
</span></span></span><span class="line"><span class="cl"><span class="s1">        /energy-full-design:/ {efd=$2}\
</span></span></span><span class="line"><span class="cl"><span class="s1">        END {print ef/efd}&#39;</span><span class="k">)</span><span class="s2">) * 100 + 0.5&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">	<span class="p">|</span> bc <span class="se">\
</span></span></span><span class="line"><span class="cl">	<span class="p">|</span> cut -d<span class="s1">&#39;.&#39;</span> -f1
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Output example:</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 20</span>
</span></span></code></pre></div>
<h2 id="модуль-для-waybar">
  <a class="link" href="#%d0%bc%d0%be%d0%b4%d1%83%d0%bb%d1%8c-%d0%b4%d0%bb%d1%8f-waybar">
    #
  </a>
  Модуль для Waybar
</h2>

<p>В моём конфиге waybar <code>~/.config/waybar/config.json</code> я добавил два модуля в правую секцию, но вы можете сделать как вам удобно. В итоге я получил это:
<img
    src="/images/battery-waybar-module_hu_7adf571591eb9de4.webp"
    width="1600"
    height="1050"
    class="content-img"
    alt=""
    loading="lazy"
    decoding="async"
  /></p>
<blockquote class="markdown-blockquote">
  <p>Если вам нравятся мои обои, вы можете найти их и другие классные штуки в моём репозитории <code>dotfiles</code> на <a href="https://github.com/alchemmist/dotfiles/tree/main/wallpapers">GitHub</a>. Не забывайте: я люблю ваши звёзды!</p>

</blockquote>
<p>Посмотрим:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="err">...</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;modules-left&#34;</span><span class="p">:</span> <span class="p">[</span><span class="err">...</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;modules-center&#34;</span><span class="p">:</span> <span class="p">[</span><span class="err">...</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;modules-right&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;battery&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;custom/battery-degradation&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">	<span class="err">...</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="err">...</span>
</span></span></code></pre></div><p>Первый модуль — стандартный <code>battery</code>, у меня он отлично работает на hyprland. Здесь мы определяем уровни хорошего, предупреждающего и критического уровня заряда, задаём nerd-иконки для разных состояний батареи:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="s2">&#34;battery&#34;</span><span class="err">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;states&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;good&#34;</span><span class="p">:</span> <span class="mi">90</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;warning&#34;</span><span class="p">:</span> <span class="mi">25</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;critical&#34;</span><span class="p">:</span> <span class="mi">10</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;format&#34;</span><span class="p">:</span> <span class="s2">&#34;{icon} {capacity}%&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;format-charging&#34;</span><span class="p">:</span> <span class="s2">&#34; {capacity}%&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;format-plugged&#34;</span><span class="p">:</span> <span class="s2">&#34; {capacity}%&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;format-icons&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;󰂎&#34;</span><span class="p">,</span> <span class="s2">&#34;󰁺&#34;</span><span class="p">,</span> <span class="s2">&#34;󰁻&#34;</span><span class="p">,</span> <span class="s2">&#34;󰁼&#34;</span><span class="p">,</span> <span class="s2">&#34;󰁽&#34;</span><span class="p">,</span> <span class="s2">&#34;󰁾&#34;</span><span class="p">,</span> <span class="s2">&#34;󰁿&#34;</span><span class="p">,</span> <span class="s2">&#34;󰂀&#34;</span><span class="p">,</span> <span class="s2">&#34;󰂁&#34;</span><span class="p">,</span> <span class="s2">&#34;󰂂&#34;</span><span class="p">,</span> <span class="s2">&#34;󰁹&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;tooltip&#34;</span><span class="p">:</span> <span class="s2">&#34;{time}&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;style&#34;</span><span class="p">:</span> <span class="s2">&#34;{capacity &lt; 10 ? &#39;color: red;&#39; : &#39;color: normal;&#39;}&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span><span class="err">,</span>
</span></span></code></pre></div><p>Второй модуль — тема сегодняшнего разговора:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="s2">&#34;custom/battery-degradation&#34;</span><span class="err">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;format&#34;</span><span class="p">:</span> <span class="s2">&#34; {}%&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;interval&#34;</span><span class="p">:</span> <span class="s2">&#34;once&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;exec&#34;</span><span class="p">:</span> <span class="s2">&#34;~/scripts/battery-degradation.sh&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;tooltip&#34;</span><span class="p">:</span> <span class="kc">false</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span><span class="err">,</span>
</span></span></code></pre></div><p>Я поместил нашу команду в скрипт — так удобнее. Вы можете сделать так же, не забудьте добавить shebang <code>#!/bin/bash</code> и:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">chmod +x ~/scripts/battery-degradation.sh
</span></span></code></pre></div><p>В модуле мы определяем формат с nerd-иконкой и процентом, отключаем подсказку и устанавливаем однократный запуск при старте waybar.</p>
<p>И завершаем эти модули CSS-стилем:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="p">#</span><span class="nn">battery</span><span class="o">,</span>
</span></span><span class="line"><span class="cl"><span class="p">#</span><span class="nn">custom-battery-degradation</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">background</span><span class="p">:</span> <span class="mh">#1e1e2e</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">opacity</span><span class="p">:</span> <span class="mf">0.7</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">padding</span><span class="p">:</span> <span class="mi">0</span><span class="kt">px</span> <span class="mi">10</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">margin</span><span class="p">:</span> <span class="mi">3</span><span class="kt">px</span> <span class="mi">0</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">margin-top</span><span class="p">:</span> <span class="mi">5</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">border</span><span class="p">:</span> <span class="mi">0</span><span class="kt">px</span> <span class="kc">solid</span> <span class="mh">#181825</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">#</span><span class="nn">battery</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">padding-right</span><span class="p">:</span> <span class="mi">10</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">border-radius</span><span class="p">:</span> <span class="mi">10</span><span class="kt">px</span> <span class="mi">0</span><span class="kt">px</span> <span class="mi">0</span><span class="kt">px</span> <span class="mi">10</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">min-width</span><span class="p">:</span> <span class="mi">50</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">#</span><span class="nn">custom-battery-degradation</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">border-radius</span><span class="p">:</span> <span class="mi">0</span><span class="kt">px</span> <span class="mi">10</span><span class="kt">px</span> <span class="mi">10</span><span class="kt">px</span> <span class="mi">0</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">margin-right</span><span class="p">:</span> <span class="mi">5</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">min-width</span><span class="p">:</span> <span class="mi">35</span><span class="kt">px</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">#</span><span class="nn">battery</span><span class="p">.</span><span class="nc">critical</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">color</span><span class="p">:</span> <span class="kc">red</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Готово! В результате:
<img
    src="/images/waybar-battery-module-2_hu_6854c9035f9f40e3.webp"
    width="151"
    height="41"
    class="content-img"
    alt=""
    loading="lazy"
    decoding="async"
  /></p>
]]></content:encoded><category>linux</category></item><item><title>Очистка диска в Linux</title><link>https://alchemmist.xyz/ru/articles/linux-clean-up/</link><pubDate>Sun, 02 Feb 2025 14:18:00 +0300</pubDate><dc:creator>alchemmist</dc:creator><guid>https://alchemmist.xyz/ru/articles/linux-clean-up/</guid><description>Если вы используете Docker, хорошее начало — очистка связанных с ним данных (только если уверены, что контейнеры и тома не содержат важного):
docker system prune # 1. Очистка пакетов Советы для Arch-систем:
Поиск самых тяжёлых пакетов (топ-20):
pacman -Qi | awk &amp;#39;/^Name/{name=$3} /^Installed Size/{print $4 $5, name}&amp;#39; | sort -hr | head -n 20 Поиск неиспользуемых зависимостей:
pacman -Qdtq Внимание! В этом списке могут быть важные пакеты, которые просто никто не использует в данный момент.</description><content:encoded><![CDATA[<p>Если вы используете Docker, хорошее начало — очистка связанных с ним данных (только если уверены, что контейнеры и тома не содержат важного):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">docker system prune
</span></span></code></pre></div>
<h2 id="1-очистка-пакетов">
  <a class="link" href="#1-%d0%be%d1%87%d0%b8%d1%81%d1%82%d0%ba%d0%b0-%d0%bf%d0%b0%d0%ba%d0%b5%d1%82%d0%be%d0%b2">
    #
  </a>
  1. Очистка пакетов
</h2>

<p>Советы для Arch-систем:</p>
<p>Поиск самых тяжёлых пакетов (топ-20):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">pacman -Qi <span class="p">|</span> awk <span class="s1">&#39;/^Name/{name=$3} /^Installed Size/{print $4 $5, name}&#39;</span> <span class="p">|</span> sort -hr <span class="p">|</span> head -n <span class="m">20</span>
</span></span></code></pre></div><p>Поиск неиспользуемых зависимостей:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">pacman -Qdtq
</span></span></code></pre></div><p><strong>Внимание!</strong> В этом списке могут быть важные пакеты, которые просто никто не использует в данный момент.</p>
<p>Удаление неиспользуемых зависимостей (если уверены):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">sudo pacman -Rns <span class="k">$(</span>pacman -Qdtq<span class="k">)</span>
</span></span></code></pre></div><p>Поиск забытых пакетов (топ-20 давно неиспользуемых):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">expac --timefmt<span class="o">=</span><span class="s1">&#39;%Y-%m-%d %T&#39;</span> <span class="s1">&#39;%l %n&#39;</span> <span class="p">|</span> sort <span class="p">|</span> head -n <span class="m">20</span>
</span></span></code></pre></div><p>Очистка кэша <code>pacman</code> (сохраняет текущую и предыдущую версии пакетов):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">sudo paccache -r
</span></span></code></pre></div><p>Полная очистка кэша (оставляет только установленные версии):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">sudo paccache -r -k <span class="m">0</span>
</span></span></code></pre></div><p>Помните: после этого вы не сможете откатить пакеты без интернета.</p>

<h2 id="2-очистка-файлов">
  <a class="link" href="#2-%d0%be%d1%87%d0%b8%d1%81%d1%82%d0%ba%d0%b0-%d1%84%d0%b0%d0%b9%d0%bb%d0%be%d0%b2">
    #
  </a>
  2. Очистка файлов
</h2>

<p>Топ-15 самых тяжёлых директорий в домашнем каталоге:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">du -h ~/ --max-depth<span class="o">=</span><span class="m">1</span> <span class="p">|</span> sort -hr <span class="p">|</span> head -n <span class="m">15</span>
</span></span></code></pre></div><p>Топ-20 самых тяжёлых файлов в домашнем каталоге:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">find ~/ -type f -exec du -Sh <span class="o">{}</span> + <span class="p">|</span> sort -rh <span class="p">|</span> head -n <span class="m">20</span>
</span></span></code></pre></div><p>Этих двух команд обычно достаточно для поиска точек очистки. Можно перейти в тяжёлую директорию и повторить команду внутри неё.```</p>
]]></content:encoded><category>linux</category></item></channel></rss>