<?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>Some stuff</title><link>https://psss.site/</link><description>I don't know what is it</description><atom:link href="https://psss.site/rss.xml" rel="self" type="application/rss+xml"></atom:link><language>ru</language><copyright>Contents © 2026 &lt;a href="mailto:none@example.com"&gt;None&lt;/a&gt; 
&lt;br/&gt;
Все материалы доступны как &lt;a rel="license" href="http://creativecommons.org/publicdomain/zero/1.0/"&gt;
общественное достояние CC0 1.0 Universal (CC0 1.0) Public Domain Dedication&lt;/a&gt;.
</copyright><lastBuildDate>Wed, 28 Oct 2026 20:42:17 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Простой Logging в Python</title><link>https://psss.site/posts/python-logging/</link><dc:creator>None</dc:creator><description>&lt;p&gt;Для логирования действий в python есть модуль &lt;em&gt;logging&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Здесь во всех примерах логирование будет просто выводом в консоль,
по сути, как настраиваемые отладочные сообщения, но сам модуль
позволяет делать гораздо больше.&lt;/p&gt;
&lt;p&gt;В целом кратко:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Создается объект логгер&lt;/li&gt;
&lt;li&gt;Устанавливается уровень сообщений, которые он будет воспринимать&lt;/li&gt;
&lt;li&gt;Создаются хендлер(ы), которые будут заниматься выводом логов (в файл, в консоль...)&lt;/li&gt;
&lt;li&gt;Устанавливается уровень вывода для каждого хендлера (например,
в консоль могут выводиться только ошибки, а в файл записываться ошибки и предупреждения).&lt;/li&gt;
&lt;li&gt;Создаются форматтеры (определяют формат вывода сообщений в логи)&lt;/li&gt;
&lt;li&gt;Форматтеры привязываются к хендлерам&lt;/li&gt;
&lt;li&gt;Хендлеры привязываются к логгерам (один логгер может иметь сразу несколько
разных хендлеров одновременно, например, для вывода и в файл и в консоль).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Само собой всё это гибко настраивается и расширяется/дополняется при необходимости.&lt;/p&gt;
&lt;p&gt;Пример начальной инициализации:&lt;/p&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;logging&lt;/span&gt;

&lt;span class="c1"&gt;# создание root логгера&lt;/span&gt;
&lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;# установка уровня логирования для всего логгера&lt;/span&gt;
&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# создание формата для вывода сообщений&lt;/span&gt;
&lt;span class="n"&gt;formatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Formatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;%(levelname)s&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="si"&gt;%(name)s&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="si"&gt;%(message)s&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;#formatter = logging.Formatter("%(filename)s:%(lineno)d: %(name)s %(funcName)s: %(message)s")&lt;/span&gt;

&lt;span class="c1"&gt;# создание StreamHandler - то есть потокового вывода&lt;/span&gt;
&lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StreamHandler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# установка уровня логирования для текущего хендлера &lt;/span&gt;
&lt;span class="c1"&gt;# (может отличаться от уровня для всего логгера)&lt;/span&gt;
&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Привязка ранее созданного формата к хендлеру&lt;/span&gt;
&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setFormatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;formatter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Привязка ранее созданного хендлера к логгеру&lt;/span&gt;
&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Вывод в лог сообщений разного уровня:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;critical&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"All is lost and nothing can be done."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Unable to open input file &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;infile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Config file not found. Using defaults"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"SSL verify disabled"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"id=&lt;/span&gt;&lt;span class="si"&gt;%d&lt;/span&gt;&lt;span class="s2"&gt;, name=&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;, full_name=&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;, url=&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_fname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Передавать созданный логгер, например, в классы или подмодули не обязательно.
Можно одной строкой создать дочерний логгер и он будет выводить через родительский,
со всеми его привязками и настройками, без дополнительных настроек (само собой,
при желании можно часть или все настройки поменять, не затрагивая родительский).&lt;/p&gt;
&lt;p&gt;Создать дочерний логгер с заданным именем:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;NewShinyClass&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# создание дочернего логгера в классе&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'pygogs'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;some_member&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Entering advanced mode"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Если надо сделать условие на текущий реальный уровень
логгирования (с учетом родительско-дочерних отношений
логгеров) то так:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getEffectiveLevel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Scan source dirs...:"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;do_scan&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Scan complete"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Если скрипт является консольным приложением с поддержкой
аргументов командно строки, то можно сделать (как это обычно
принято у консольных приложений) аргумент &lt;em&gt;verbose&lt;/em&gt; или &lt;em&gt;-v&lt;/em&gt; и 
чем больше таких аргументов, тем подробнее вывод.&lt;/p&gt;
&lt;p&gt;В примере разбор аргументов сделан при помощи 
типового &lt;em&gt;argparse&lt;/em&gt;.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="ch"&gt;#!/usr/bin/env python3&lt;/span&gt;
&lt;span class="c1"&gt;# -*- coding: utf-8 -*-&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;argparse&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;logging&lt;/span&gt;

&lt;span class="n"&gt;__version__&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"1.0"&lt;/span&gt;

&lt;span class="c1"&gt;###############################################################################&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="n"&gt;descr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"My super script"&lt;/span&gt;
  &lt;span class="n"&gt;additional&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"just example"&lt;/span&gt;
  &lt;span class="n"&gt;parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;argparse&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ArgumentParser&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;descr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="n"&gt;epilog&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;additional&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'--version'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'version'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                      &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="si"&gt;%(prog)s&lt;/span&gt;&lt;span class="s1"&gt; '&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;__version__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"-v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"--verbose"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"count"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"increase verbosity"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse_args&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="c1"&gt;# уровень логгирования в зависимости от количества параметров -v&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;verbose&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="n"&gt;lvl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WARNING&lt;/span&gt;
  &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;verbose&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;lvl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;                   &lt;span class="n"&gt;lvl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DEBUG&lt;/span&gt;

  &lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lvl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="n"&gt;formatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Formatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;%(levelname)s&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="si"&gt;%(message)s&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StreamHandler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lvl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setFormatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;formatter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="o"&gt;.....&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

&lt;span class="c1"&gt;###############################################################################&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'__main__'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Отличное подробное видео на тему: &lt;a href="https://youtu.be/jF_XglX0JgM"&gt;https://youtu.be/jF_XglX0JgM&lt;/a&gt;&lt;/p&gt;</description><category>python</category><guid>https://psss.site/posts/python-logging/</guid><pubDate>Tue, 27 Oct 2026 17:59:09 GMT</pubDate></item><item><title>Linux автологин</title><link>https://psss.site/posts/linux-console-autologin/</link><dc:creator>None</dc:creator><description>&lt;p&gt;Если речь идёт про консоль и система оборудована &lt;code&gt;systemd&lt;/code&gt;,
то надо добавить файл &lt;code&gt;/etc/systemd/system/getty@tty1.service.d/override.conf&lt;/code&gt; &lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="k"&gt;[Service]&lt;/span&gt;
&lt;span class="na"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="na"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;-/sbin/agetty --autologin UserName --noclear %I 38400 linux&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Ещё информация: 
&lt;a href="https://linuxvox.com/blog/linux-autologin/"&gt;https://linuxvox.com/blog/linux-autologin/&lt;/a&gt;&lt;/p&gt;</description><category>linux</category><guid>https://psss.site/posts/linux-console-autologin/</guid><pubDate>Thu, 24 Sep 2026 11:09:24 GMT</pubDate></item><item><title>bash: условие если вывод команды содержит строку</title><link>https://psss.site/posts/bash-if-grep/</link><dc:creator>None</dc:creator><description>&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;SomeCommand&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;-q&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'TextToFind'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&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;"TextToFind was found in SomeCommand output"&lt;/span&gt;
&lt;span class="k"&gt;else&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;"No TextToFind in SomeCommand output found"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;</description><category>bash</category><category>linux</category><guid>https://psss.site/posts/bash-if-grep/</guid><pubDate>Thu, 24 Sep 2026 10:21:03 GMT</pubDate></item><item><title>bash: запуск процессов на фоне</title><link>https://psss.site/posts/bash-detach/</link><dc:creator>None</dc:creator><description>&lt;p&gt;Если надо запустить скрипт на фоне 
(типовая ситуация - запуск скрипта как CGI из веб-сервера),
то перед запуском долгого процесса надо отсоединить
stdout и stderr от скрипта. Тогда веб-сервер сможет
продолжать работать.&lt;/p&gt;
&lt;p&gt;Делается это так (перед запуском фоновой задачи):&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nb"&gt;exec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;-
&lt;span class="nb"&gt;exec&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;/pre&gt;&lt;/div&gt;

&lt;p&gt;Источники:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/6033780/run-a-cgi-shell-script-in-background"&gt;https://stackoverflow.com/questions/6033780/run-a-cgi-shell-script-in-background&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://tldp.org/LDP/abs/html/io-redirection.html"&gt;https://tldp.org/LDP/abs/html/io-redirection.html&lt;/a&gt;&lt;/p&gt;</description><category>bash</category><category>linux</category><guid>https://psss.site/posts/bash-detach/</guid><pubDate>Thu, 24 Sep 2026 10:17:16 GMT</pubDate></item><item><title>Настройка nginx для вызова скриптов через CGI</title><link>https://psss.site/posts/nginx_cgi/</link><dc:creator>None</dc:creator><description>&lt;p&gt;&lt;code&gt;nginx&lt;/code&gt; будет работать через FastCGI c сервером
&lt;code&gt;fcgiwrap&lt;/code&gt;, который и будет запускать скрипты через CGI.&lt;/p&gt;
&lt;h3&gt;Установка и настройка&lt;/h3&gt;
&lt;p&gt;Дальнейшие действия следует производить от имени &lt;em&gt;root&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Установить серверы:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;apt&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;nginx-full&lt;span class="w"&gt; &lt;/span&gt;fcgiwrap
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Создать файл конфигурации &lt;code&gt;/etc/nginx/fcgiwrap.conf&lt;/code&gt; для &lt;code&gt;nginx&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cgi&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&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="n"&gt;gzip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;off&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;fastcgi_pass&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;unix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fcgiwrap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nginx&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fastcgi_params&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;fastcgi_param&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SCRIPT_FILENAME&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;document_root&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;fastcgi_script_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Создать каталог для cgi-скриптов:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="n"&gt;mkdir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cgi&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;
&lt;span class="n"&gt;chmod&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;755&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cgi&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Добавить в файл конфигурации &lt;code&gt;/etc/nginx/sites-available/default&lt;/code&gt;
строку &lt;code&gt;include fcgiwrap.conf;&lt;/code&gt;&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nv"&gt;server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{
&lt;span class="w"&gt;        &lt;/span&gt;.....
&lt;span class="w"&gt;        &lt;/span&gt;.....
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;fcgiwrap&lt;/span&gt;.&lt;span class="nv"&gt;conf&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
}
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Включить &lt;code&gt;fcgiwrap&lt;/code&gt; и перезапустить &lt;code&gt;nginx&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;systemctl enable fcgiwrap
systemctl restart nginx
&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Проверка&lt;/h3&gt;
&lt;p&gt;Создать тестовый файл &lt;code&gt;/var/www/cgi-bin/index.cgi&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="ch"&gt;#!/usr/bin/env python3&lt;/span&gt;

&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Content-type: text/html&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;html&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;body&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;div style=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;width: 100%; font-size: 40px; font-weight: bold; text-align: center;&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"CGI Script Test Page"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;/div&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;/body&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Сделать файл исполняемым&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;chmod&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;705&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/var/www/cgi-bin/index.cgi
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Проверить можно по ссылке вида &lt;strong&gt;http://servername/cgi-bin/index.cgi&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Скрипт не обязательно должен быть на &lt;code&gt;python&lt;/code&gt;, можно использовать &lt;code&gt;bash&lt;/code&gt;.&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;printf&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Content-type: text/html\r\n"&lt;/span&gt;
&lt;span class="nb"&gt;printf&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"\r\n"&lt;/span&gt;
&lt;span class="nb"&gt;printf&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;html&amp;gt;\n&amp;lt;body&amp;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;"&amp;lt;div style=\"width: 100%; font-size: 40px; font-weight: bold; text-align: center;\"&amp;gt;"&lt;/span&gt;
&lt;span class="nb"&gt;printf&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CGI Script Test Page"&lt;/span&gt;
&lt;span class="nb"&gt;printf&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;/div&amp;gt;\n"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;whoami&lt;span class="sb"&gt;`&lt;/span&gt;

&lt;span class="nb"&gt;printf&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;/body&amp;gt;\n&amp;lt;/html&amp;gt;\r\n"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Источник: &lt;a href="https://www.server-world.info/en/note?os=Debian_11&amp;amp;p=nginx&amp;amp;f=8"&gt;https://www.server-world.info/en/note?os=Debian_11&amp;amp;p=nginx&amp;amp;f=8&lt;/a&gt;&lt;/p&gt;</description><category>linux</category><guid>https://psss.site/posts/nginx_cgi/</guid><pubDate>Wed, 15 Jul 2026 13:48:21 GMT</pubDate></item><item><title>Преобразовать svg в pdf</title><link>https://psss.site/posts/svg2pdf/</link><dc:creator>None</dc:creator><description>&lt;h2&gt;Преобразовать SVG в PDF&lt;/h2&gt;
&lt;p&gt;Преобразовать &lt;em&gt;svg&lt;/em&gt; файл в &lt;em&gt;pdf&lt;/em&gt; можно при помощи
программы &lt;code&gt;rsvg-convert&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Для установки её в Debian:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;apt install librsvg2-bin
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Для Windows всё немного сложнее, понадобится &lt;a href="https://github.com/msys2/msys2-installer/releases"&gt;MSYS&lt;/a&gt;.
В его терминале выполнить:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;pacman -S mingw-w64-ucrt-x86_64-librsvg
&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Обрезать PDF&lt;/h2&gt;
&lt;h3&gt;Вариант 1. pdfcropmargins&lt;/h3&gt;
&lt;p&gt;Установить можно через &lt;code&gt;pip3&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;pip3 install pdfCropMargins --upgrade --only-binary pymupdf
&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Вариант 2. pdfcrop&lt;/h3&gt;
&lt;p&gt;Для обрезки pdf-файлов можно использовать &lt;code&gt;pdfcrop&lt;/code&gt; из состава &lt;em&gt;TeXLive&lt;/em&gt;.
Под Windows надо установить &lt;em&gt;TeXLive&lt;/em&gt;, для Debian можно только часть (но зависимостей будет много):&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;apt install texlive-extra-utils
&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Скрипт для преобразования всех SVG файлов в каталоге&lt;/h2&gt;
&lt;h3&gt;При использовании &lt;code&gt;pdfcropmargins&lt;/code&gt;:&lt;/h3&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="ch"&gt;#!/bin/sh&lt;/span&gt;

rm&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;*.pdf
&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;v&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;*.svg
&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&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;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$v&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="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;FNAME&lt;/span&gt;&lt;span class="o"&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;v&lt;/span&gt;&lt;span class="p"&gt;%.*&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;rsvg-convert&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;pdf&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$FNAME&lt;/span&gt;&lt;span class="s2"&gt;.pdf"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$v&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;pdfcropmargins&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-p4&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&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;$FNAME&lt;/span&gt;&lt;span class="s2"&gt;.pdf"&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;При использовании &lt;code&gt;pdfcrop&lt;/code&gt;:&lt;/h3&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="ch"&gt;#!/bin/sh&lt;/span&gt;

rm&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;*.pdf
&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;v&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;*.svg
&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&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;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$v&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="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;FNAME&lt;/span&gt;&lt;span class="o"&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;v&lt;/span&gt;&lt;span class="p"&gt;%.*&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;rsvg-convert&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;pdf&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$FNAME&lt;/span&gt;&lt;span class="s2"&gt;.pdf"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$v&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;pdfcrop&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$FNAME&lt;/span&gt;&lt;span class="s2"&gt;.pdf"&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Windows&lt;/h3&gt;
&lt;p&gt;bat-файл для Windows для преобразования одного файла:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="k"&gt;echo&lt;/span&gt; off

&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;: FNAME=имя файла без расширения&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nv"&gt;FNAME&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;%~n1&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nv"&gt;RSVG_PATH&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;C:\msys2\ucrt64\bin

&lt;span class="nv"&gt;%RSVG_PATH%&lt;/span&gt;\rsvg-convert.exe -f pdf -o &lt;span class="nv"&gt;%FNAME%&lt;/span&gt;.pdf &lt;span class="nv"&gt;%FNAME%&lt;/span&gt;.svg

pdfcropmargins -p 0 -p4 0 0 0 0 -A &lt;span class="nv"&gt;%FNAME%&lt;/span&gt;.pdf
&lt;/pre&gt;&lt;/div&gt;</description><category>linux</category><category>misc</category><guid>https://psss.site/posts/svg2pdf/</guid><pubDate>Sun, 12 Jul 2026 08:40:31 GMT</pubDate></item><item><title>Системные сертификаты в python requests</title><link>https://psss.site/posts/python-requests-ssl-certificate/</link><dc:creator>None</dc:creator><description>&lt;p&gt;При запросе по &lt;em&gt;https&lt;/em&gt; при помощи &lt;code&gt;requests&lt;/code&gt; из скрипта на python
есть несколько вариантов для проверки сертификата.
За это отвечает параметр &lt;code&gt;verify&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Отключение проверки&lt;/h3&gt;
&lt;p&gt;Если параметр &lt;code&gt;verify&lt;/code&gt; равен &lt;em&gt;False&lt;/em&gt;, то проверка будет отключена.
Это в целом нехорошо, да и будут выводиться всякие предупреждения.
Для закрытой локалки как временное решение может и сойдёт...&lt;/p&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;requests&lt;/span&gt;

&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&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="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verify&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Проверка по умолчанию&lt;/h3&gt;
&lt;p&gt;Если параметр &lt;code&gt;verify&lt;/code&gt; равен &lt;em&gt;True&lt;/em&gt; (это значение по умолчанию),
то проверка будет проводиться на соответствие 
&lt;a href="https://github.com/certifi/python-certifi"&gt;python-certifi&lt;/a&gt;.&lt;/p&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;requests&lt;/span&gt;

&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&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="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verify&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Проверка "вручную"&lt;/h3&gt;
&lt;p&gt;Можно вручную сохранить сертификаты в текстовый файл 
(всю цепочку, от корневого центра до сертификата сайта) и
путь до этого файла дать в качестве параметра. Тогда
сертификаты будут проверяться на соответствие сохраненным 
в этом файле. &lt;/p&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;requests&lt;/span&gt;

&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&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="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verify&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'/path/to/certfile'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Использование системных сертификатов&lt;/h3&gt;
&lt;p&gt;Обычная включенная проверка (&lt;code&gt;verify=True&lt;/code&gt;) проверяет
сертификаты "встроенные" в &lt;code&gt;certifi&lt;/code&gt;, при этом игнорируя
сертификаты установленные в системе. Иногда это неудобно.
Решением данной проблемы может служить установка
пакета &lt;code&gt;pip-system-certs&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;pip3 install pip-system-certs
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;После этого обычная проверка (&lt;code&gt;verify=True&lt;/code&gt;) будет учитывать
установленные в системе сертификаты.&lt;/p&gt;
&lt;p&gt;Источник: &lt;a href="https://stackoverflow.com/questions/50422136/python-requests-with-wincertstore"&gt;https://stackoverflow.com/questions/50422136/python-requests-with-wincertstore&lt;/a&gt;&lt;/p&gt;</description><category>python</category><guid>https://psss.site/posts/python-requests-ssl-certificate/</guid><pubDate>Wed, 29 Apr 2026 11:44:30 GMT</pubDate></item><item><title>LaTeX: параметры ключ=значение</title><link>https://psss.site/posts/latex-keyval/</link><dc:creator>None</dc:creator><description>&lt;p&gt;Определение команды:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="k"&gt;\ExplSyntaxOn&lt;/span&gt;

&lt;span class="k"&gt;\keys_define:nn&lt;/span&gt; &lt;span class="nb"&gt;{&lt;/span&gt; mymodule &lt;span class="nb"&gt;}&lt;/span&gt;
  &lt;span class="nb"&gt;{&lt;/span&gt;
    color .tl&lt;span class="nb"&gt;_&lt;/span&gt;set:N = &lt;span class="k"&gt;\l_mymodule_color_tl&lt;/span&gt; ,
    color .initial:n = &lt;span class="nb"&gt;{&lt;/span&gt; black &lt;span class="nb"&gt;}&lt;/span&gt; ,
    text .tl&lt;span class="nb"&gt;_&lt;/span&gt;set:N = &lt;span class="k"&gt;\l_mymodule_text_tl&lt;/span&gt; ,
    text .initial:n = &lt;span class="nb"&gt;{&lt;/span&gt; Default~Text &lt;span class="nb"&gt;}&lt;/span&gt; ,
    size .dim&lt;span class="nb"&gt;_&lt;/span&gt;set:N = &lt;span class="k"&gt;\l_mymodule_size_dim&lt;/span&gt; ,
    size .initial:n = &lt;span class="nb"&gt;{&lt;/span&gt; 12pt &lt;span class="nb"&gt;}&lt;/span&gt; ,
  &lt;span class="nb"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;\NewDocumentCommand&lt;/span&gt; &lt;span class="nb"&gt;{&lt;/span&gt; &lt;span class="k"&gt;\mycommand&lt;/span&gt; &lt;span class="nb"&gt;}&lt;/span&gt; &lt;span class="nb"&gt;{&lt;/span&gt; O&lt;span class="nb"&gt;{}&lt;/span&gt; &lt;span class="nb"&gt;}&lt;/span&gt;
  &lt;span class="nb"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;\keys_set:nn&lt;/span&gt; &lt;span class="nb"&gt;{&lt;/span&gt; mymodule &lt;span class="nb"&gt;}&lt;/span&gt; &lt;span class="nb"&gt;{&lt;/span&gt; #1 &lt;span class="nb"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;\group_begin:&lt;/span&gt;
      &lt;span class="k"&gt;\color&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;&lt;span class="k"&gt;\l_mymodule_color_tl&lt;/span&gt;&lt;span class="nb"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;\fontsize&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;&lt;span class="k"&gt;\l_mymodule_size_dim&lt;/span&gt;&lt;span class="nb"&gt;}{&lt;/span&gt;&lt;span class="k"&gt;\dim_eval:n&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;&lt;span class="k"&gt;\l_mymodule_size_dim&lt;/span&gt; * 1.2&lt;span class="nb"&gt;}}&lt;/span&gt;&lt;span class="k"&gt;\selectfont&lt;/span&gt;
      &lt;span class="k"&gt;\l_mymodule_text_tl&lt;/span&gt;
    &lt;span class="k"&gt;\group_end:&lt;/span&gt;
  &lt;span class="nb"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;\ExplSyntaxOff&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Использование:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="k"&gt;\begin&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;document&lt;span class="nb"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;\mycommand&lt;/span&gt; &lt;span class="c"&gt;% Uses default values&lt;/span&gt;
&lt;span class="k"&gt;\par&lt;/span&gt;
&lt;span class="k"&gt;\mycommand&lt;/span&gt;&lt;span class="na"&gt;[color=blue, text=Hello~World, size=18pt]&lt;/span&gt;
&lt;span class="k"&gt;\par&lt;/span&gt;
&lt;span class="k"&gt;\mycommand&lt;/span&gt;&lt;span class="na"&gt;[size=24pt, color=red]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Свойства ключей в &lt;code&gt;keys_define&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Каждый ключ в &lt;code&gt;keys_define&lt;/code&gt; может иметь набор свойств:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.code:n&lt;/code&gt; = &lt;em&gt;code to execute&lt;/em&gt;: задает код для выполнения, когда ключ задан, 
при этом в коде может использоваться &lt;code&gt;#1&lt;/code&gt; и туда будет подставлено значение ключа. &lt;/li&gt;
&lt;li&gt;&lt;code&gt;.initial:n&lt;/code&gt; = &lt;em&gt;initial value&lt;/em&gt;: Задает начальное значение. 
Оно будет использоваться, если ключ вообще не задан.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.default:n&lt;/code&gt; = &lt;em&gt;default value&lt;/em&gt;: Задает значение по умолчанию.
Оно будет использоваться если ключ задан без значения (например, key=).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.choices:nn&lt;/code&gt; = &lt;em&gt;{ список выбора }&lt;/em&gt;: Задает список допустимых значений для ключа. 
Для каждого возможного значения задается код, который должен выполниться в соответствующем случае.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.bool_set:N&lt;/code&gt;, &lt;code&gt;.bool_set_true:N&lt;/code&gt;, &lt;code&gt;.bool_set_false:N&lt;/code&gt;: Задает что делать для boolean-ключей, 
установить значение, true или false.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.int_set:N&lt;/code&gt;, &lt;code&gt;.dim_set:N&lt;/code&gt;, &lt;code&gt;.tl_set:N&lt;/code&gt;: Задает присвоение переменным для числа, размера или строки.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Пример:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="k"&gt;\ExplSyntaxOn&lt;/span&gt;
&lt;span class="k"&gt;\keys_define:nn&lt;/span&gt; &lt;span class="nb"&gt;{&lt;/span&gt; mymodule &lt;span class="nb"&gt;}&lt;/span&gt;
  &lt;span class="nb"&gt;{&lt;/span&gt;
    color .code:n = &lt;span class="k"&gt;\tl_set:Nn&lt;/span&gt; &lt;span class="k"&gt;\l_mymodule_color_tl&lt;/span&gt; &lt;span class="nb"&gt;{&lt;/span&gt; #1 &lt;span class="nb"&gt;}&lt;/span&gt;,
    color .initial:n = black,
    shape .choices:nn =
      &lt;span class="nb"&gt;{&lt;/span&gt;
        circle .code:n = &lt;span class="k"&gt;\tl_set:Nn&lt;/span&gt; &lt;span class="k"&gt;\l_mymodule_shape_tl&lt;/span&gt; &lt;span class="nb"&gt;{&lt;/span&gt; circle &lt;span class="nb"&gt;}&lt;/span&gt;,
        square .code:n = &lt;span class="k"&gt;\tl_set:Nn&lt;/span&gt; &lt;span class="k"&gt;\l_mymodule_shape_tl&lt;/span&gt; &lt;span class="nb"&gt;{&lt;/span&gt; square &lt;span class="nb"&gt;}&lt;/span&gt;
      &lt;span class="nb"&gt;}&lt;/span&gt;,
    shape .initial:n = circle,
    linewidth .int&lt;span class="nb"&gt;_&lt;/span&gt;set:N = &lt;span class="k"&gt;\l_mymodule_linewidth_int&lt;/span&gt;,
    linewidth .initial:n = 1
  &lt;span class="nb"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\ExplSyntaxOff&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;В этом примере определены ключи &lt;em&gt;color&lt;/em&gt;, &lt;em&gt;shape&lt;/em&gt; и &lt;em&gt;linewidth&lt;/em&gt; для модуля &lt;em&gt;mymodule&lt;/em&gt;. &lt;/p&gt;
&lt;p&gt;&lt;em&gt;color&lt;/em&gt; принимает значение, &lt;em&gt;shape&lt;/em&gt; значение из списка, a &lt;em&gt;linewidth&lt;/em&gt; задает числовую переменную.&lt;/p&gt;</description><category>LaTeX</category><guid>https://psss.site/posts/latex-keyval/</guid><pubDate>Tue, 21 Oct 2025 22:42:06 GMT</pubDate></item><item><title>LaTeX mbox на список</title><link>https://psss.site/posts/latex-mbox/</link><dc:creator>None</dc:creator><description>&lt;p&gt;Есть: строка, разделенная запятыми. &lt;/p&gt;
&lt;p&gt;Надо: завернуть каждый элемент отдельно в функцию (например, в &lt;em&gt;\mbox&lt;/em&gt;) и
собрать строку обратно, возможно с другими разделителями.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="k"&gt;\ExplSyntaxOn&lt;/span&gt;

&lt;span class="k"&gt;\NewDocumentCommand&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;&lt;span class="k"&gt;\MBoxingList&lt;/span&gt;&lt;span class="nb"&gt;}{&lt;/span&gt;O&lt;span class="nb"&gt;{&lt;/span&gt;,&lt;span class="k"&gt;\&lt;/span&gt; &lt;span class="nb"&gt;}&lt;/span&gt;m&lt;span class="nb"&gt;}&lt;/span&gt;
&lt;span class="nb"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;\seq_clear_new:N&lt;/span&gt; &lt;span class="k"&gt;\l__in_seq&lt;/span&gt;
  &lt;span class="k"&gt;\seq_set_from_clist:Nn&lt;/span&gt; &lt;span class="k"&gt;\l__in_seq&lt;/span&gt; &lt;span class="nb"&gt;{&lt;/span&gt;#2&lt;span class="nb"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;\seq_set_map:NNn&lt;/span&gt; &lt;span class="k"&gt;\l__in_seq&lt;/span&gt; &lt;span class="k"&gt;\l__in_seq&lt;/span&gt; &lt;span class="nb"&gt;{&lt;/span&gt;&lt;span class="k"&gt;\mbox&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;##1&lt;span class="nb"&gt;}}&lt;/span&gt;
  &lt;span class="k"&gt;\seq_use:Nn&lt;/span&gt; &lt;span class="k"&gt;\l__in_seq&lt;/span&gt; &lt;span class="nb"&gt;{&lt;/span&gt;#1&lt;span class="nb"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;%  \quad\seq_count:N \l__in_seq&lt;/span&gt;
&lt;span class="nb"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;\ExplSyntaxOff&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Использовать так: `\expanded{\MBoxingList[, ]{123, 123, 5234, 6543}}&lt;/p&gt;
&lt;p&gt;Как вариант определить через &lt;code&gt;\NewExpandableDocumentCommand&lt;/code&gt;, но тогда
вызывать без &lt;code&gt;\expanded&lt;/code&gt; и могут быть сюрпризы если исходная строка передается
не явно, а определена командой.&lt;/p&gt;
&lt;p&gt;P.S. Вроде и работает, но с этим expansion что-нибудь да не нравится. 
В общем, глаз да глаз.&lt;/p&gt;
&lt;p&gt;P.P.S. Можно попробовать через пакет &lt;code&gt;listofitems&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;P.P.P.S Есть какое-то решение на классическом синтаксисе:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="k"&gt;\makeatletter&lt;/span&gt;

&lt;span class="c"&gt;% Functional foreach construct&lt;/span&gt;
&lt;span class="c"&gt;% #1 - Function to call on each comma-separated item in #3&lt;/span&gt;
&lt;span class="c"&gt;% #2 - Parameter to pass to function in #1 as first parameter&lt;/span&gt;
&lt;span class="c"&gt;% #3 - Comma-separated list of items to pass as second parameter to function #1&lt;/span&gt;
&lt;span class="k"&gt;\def\foreach&lt;/span&gt;#1#2#3&lt;span class="nb"&gt;{&lt;/span&gt;&lt;span class="c"&gt;%&lt;/span&gt;
  &lt;span class="k"&gt;\@test@foreach&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;#1&lt;span class="nb"&gt;}{&lt;/span&gt;#2&lt;span class="nb"&gt;}&lt;/span&gt;#3,&lt;span class="k"&gt;\@end@token&lt;/span&gt;&lt;span class="c"&gt;%&lt;/span&gt;
&lt;span class="nb"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;% Internal helper function - Eats one input&lt;/span&gt;
&lt;span class="k"&gt;\def\@swallow&lt;/span&gt;#1&lt;span class="nb"&gt;{}&lt;/span&gt;

&lt;span class="c"&gt;% Internal helper function - Checks the next character after #1 and #2 and&lt;/span&gt;
&lt;span class="c"&gt;% continues loop iteration if \@end@token is not found&lt;/span&gt;
&lt;span class="k"&gt;\def\@test@foreach&lt;/span&gt;#1#2&lt;span class="nb"&gt;{&lt;/span&gt;&lt;span class="c"&gt;%&lt;/span&gt;
  &lt;span class="k"&gt;\@ifnextchar\@end@token&lt;/span&gt;&lt;span class="c"&gt;%&lt;/span&gt;
    &lt;span class="nb"&gt;{&lt;/span&gt;&lt;span class="k"&gt;\@swallow&lt;/span&gt;&lt;span class="nb"&gt;}&lt;/span&gt;&lt;span class="c"&gt;%&lt;/span&gt;
    &lt;span class="nb"&gt;{&lt;/span&gt;&lt;span class="k"&gt;\@foreach&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;#1&lt;span class="nb"&gt;}{&lt;/span&gt;#2&lt;span class="nb"&gt;}}&lt;/span&gt;&lt;span class="c"&gt;%&lt;/span&gt;
&lt;span class="nb"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;% Internal helper function - Calls #1{#2}{#3} and recurses&lt;/span&gt;
&lt;span class="c"&gt;% The magic of splitting the third parameter occurs in the pattern matching of the \def&lt;/span&gt;
&lt;span class="k"&gt;\def\@foreach&lt;/span&gt;#1#2#3,#4&lt;span class="k"&gt;\@end@token&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;&lt;span class="c"&gt;%&lt;/span&gt;
  #1&lt;span class="nb"&gt;{&lt;/span&gt;#2&lt;span class="nb"&gt;}{&lt;/span&gt;#3&lt;span class="nb"&gt;}&lt;/span&gt;&lt;span class="c"&gt;%&lt;/span&gt;
  &lt;span class="k"&gt;\@test@foreach&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;#1&lt;span class="nb"&gt;}{&lt;/span&gt;#2&lt;span class="nb"&gt;}&lt;/span&gt;#4&lt;span class="k"&gt;\@end@token&lt;/span&gt;&lt;span class="c"&gt;%&lt;/span&gt;
&lt;span class="nb"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;\makeatother&lt;/span&gt;

&lt;span class="c"&gt;%% Функция для использования&lt;/span&gt;
&lt;span class="k"&gt;\def\makembox&lt;/span&gt;#1#2&lt;span class="nb"&gt;{&lt;/span&gt;&lt;span class="k"&gt;\mbox&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;#2&lt;span class="nb"&gt;}&lt;/span&gt;, &lt;span class="nb"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;</description><category>LaTeX</category><guid>https://psss.site/posts/latex-mbox/</guid><pubDate>Sun, 19 Oct 2025 20:47:17 GMT</pubDate></item><item><title>HTML redirect</title><link>https://psss.site/posts/html-redirect/</link><dc:creator>None</dc:creator><description>&lt;p&gt;Перенаправить статически страницу
можно html-тегом &lt;code&gt;&amp;lt;meta...&lt;/code&gt; внутри &lt;code&gt;&amp;lt;head&amp;gt;...&amp;lt;/head&amp;gt;&lt;/code&gt;, можно 
при помощи &lt;em&gt;javascript&lt;/em&gt;. Лучше использовать и то и другое.
И на всякий случай ещё и явную ссылку, вдруг у кого-то браузер 
сам не перейдёт.&lt;/p&gt;
&lt;p&gt;Вот пример:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE HTML&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;html&lt;/span&gt; &lt;span class="na"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"en-US"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;meta&lt;/span&gt; &lt;span class="na"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="cm"&gt;&amp;lt;!-- html redirect with timeout=0 --&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;meta&lt;/span&gt; &lt;span class="na"&gt;http-equiv&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"refresh"&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"0; url=http://example.com"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="cm"&gt;&amp;lt;!-- for search engines --&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;link&lt;/span&gt; &lt;span class="na"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"canonical"&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"http://www.example.com"&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="cm"&gt;&amp;lt;!-- javascript redirect --&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&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;"http://example.com"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Page Redirection&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="cm"&gt;&amp;lt;!-- Note: don't tell people to `click` the link, &lt;/span&gt;
&lt;span class="cm"&gt;       just tell them that it is a link. --&amp;gt;&lt;/span&gt;
  If you are not redirected automatically, 
  follow this &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'http://example.com'&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;link to example&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;.
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;</description><category>misc</category><guid>https://psss.site/posts/html-redirect/</guid><pubDate>Thu, 09 Oct 2025 12:20:33 GMT</pubDate></item></channel></rss>