Helcode | Хелкод | Скрипты и автоматизация
992 subscribers
52 photos
34 links
☎️ Контакты для связи: @helcodeadm
Download Telegram
tree — показать структуру папок красиво

Ситуация: вы пришли в новый проект. Внутри — 50 папок и 200 файлов. Как понять, что где лежит? ls -la покажет список, но не даст представления о вложенности. find . вывалит простыню.

tree выводит структуру файлов и папок в виде дерева. С первого взгляда видно, какие папки внутри каких лежат, где глубина, где пустота.

Базовое использование:
# Показать дерево текущей папки
tree

# Показать дерево конкретной папки
tree /home/user/project

Пример вывода:
.
├── app.py
├── config
│ ├── settings.py
│ └── logging.conf
├── requirements.txt
├── static
│ ├── css
│ │ └── style.css
│ └── js
│ └── main.js
└── templates
├── index.html
└── article.html

Вариант 1 (Ограничить глубину):
# Только два уровня вложенности
tree -L 2 /home/user/project

Вариант 2 (Показать только папки, без файлов):
tree -d /home/user/project

Вариант 3 (Показать скрытые файлы):
tree -a /home/user/project

Вариант 4 (Подсветка по типам файлов):
tree -C /home/user/project

Исполняемые файлы — зелёным, папки — синим, архивы — красным.

Вариант 5 (Сохранить дерево в файл):
tree /home/user/project > structure.txt

Вариант 6 (Исключить определённые папки):
tree --prune --matchdirs --dirsfirst -I "node_modules|.git|__pycache__"

Не показывать node_modules, .git и pycache.

Вариант 7 (Показать размер файлов):
tree --du -h

--du — показать суммарный размер папки, -h — человеко-читаемый формат.

Вариант 8 (С XML/JSON выводом для скриптов):
tree --xml > structure.xml
tree --json > structure.json

Красивые варианты:
# Ограничить глубину 2, показать папки первыми, исключить мусор
tree -L 2 -d --dirsfirst -I "venv|.idea|.pytest_cache|__pycache__|.git"

# С размерами файлов, глубиной 3, только папки
tree -L 3 -d --du -h

# Цветной вывод с папками первыми, без файлов
tree -C -d --dirsfirst

Совет: добавьте в ~/.bashrc алиас:
alias tree='tree -C --dirsfirst'

Теперь всегда будет цветной вывод и папки сверху.

Используете tree для навигации или предпочитаете ls -R?

P.S. Самый недооценённый флаг — -L. Ограничивает глубину, когда дерево слишком большое и нужно только понять общую структуру.

👉🏻 Я в Telegram - t.me/helcode
👉🏻 Я в VK - vk.com/helcode
👉🏻 Я на Boosty - boosty.to/helcode
👍143👌2
entr — запускаем команды при изменении файлов

Ситуация: вы пишете код. Каждые 30 секунд переключаетесь в терминал, нажимаете Ctrl+C, стрелку вверх, Enter, чтобы перезапустить тесты или пересобрать проект. Рутина раздражает.

entr — это утилита, которая следит за файлами и запускает команду при любом изменении. Пересохранили файл — entr сам перезапустил тесты, перекомпилировал проект или перезагрузил сервер.

Базовое использование:

# Перезапускать тесты при изменении любого .py файла
find . -name "*.py" | entr pytest

# Следить за конкретным файлом
echo app.py | entr python app.py


Вариант 1 (Автоматический перезапуск веб-сервера при разработке):

echo app.py | entr -r python app.py

-r — рестарт: убивает предыдущий процесс перед запуском нового. Идеально для серверов.

Вариант 2 (Автоматическая пересборка документации):

find docs/ -name "*.md" | entr -s "make html"

-s — выполнить команду через шелл. Позволяет использовать пайпы и составные команды.

Вариант 3 (Запуск скрипта при изменении конфига и перезагрузка сервиса):

echo /etc/nginx/nginx.conf | entr -p systemctl reload nginx

-p — не перезапускать команду, если она уже выполняется (защита от наложения).

Вариант 4 (Выполнить несколько команд при изменении):

find src/ -name "*.go" | entr -s "go test && go build -o app"


Вариант 5 (Запускать скрипт в фоне и не ждать его завершения):

find *.c | entr -n ./compile.sh

-n — не ждать завершения предыдущей команды (полезно для долгих задач в фоне).

Некоторые трюки с entr:

1. Следить за новыми файлами: по умолчанию entr следит только за файлами, которые были переданы на старте. Чтобы добавить динамически появляющиеся файлы, нужен перезапуск. Но можно использовать find повторно: while true; do find . -name "*.py" | entr -d pytest; done (флаг -d отслеживает изменение директории).

2. Перезапуск при изменении конфигурации: entr умеет получать сигналы. Если нужно перечитать конфиг без остановки, используйте -r.

3. Ограничение частоты запусков: entr запускает команду при каждом изменении. Если файл сохраняется 100 раз в секунду (бывает при автодополнении), entr может заддосить систему. Защиты встроенной нет, но можно использовать внешние утилиты вроде sleep внутри команды.

P.S. В мире Node.js есть `nodemon`, в Python — `watchdog`, в Go — `fresh`. Но `entr` работает с любым языком и не требует установки дополнительных пакетов, кроме самой утилиты.

👉🏻 Я в Telegram - t.me/helcode
👉🏻 Я в VK - vk.com/helcode
👉🏻 Я на Boosty - boosty.to/helcode
👍54🔥2
duf — анализ дисков, который не напрягает глаза

Вы наверняка знаете df -h. Но давайте честно: его вывод — серое полотно, в котором глаза цепляются за проценты, а колонки разъезжаются, если подключено много устройств.

duf — это df, который сделали нормальные люди. Таблицы, цвета, сортировка, фильтрация и даже JSON для скриптов.

Базовое использование:

duf


Вы увидите:
- все разделы, смонтированные устройства, Docker-тома (если есть)
- колонки: размер, использовано, свободно, процент, точка монтирования
- цветовую индикацию: зелёный — норма, жёлтый — близко к заполнению, красный — опасно

Вариант 1 (Показать только реальные диски, исключить tmpfs, devtmpfs, squashfs):

duf --only ext4,xfs,btrfs,zfs


Вариант 2 (Сортировка по любому столбцу):

duf --sort size    # самые большие сверху
duf --sort used # больше всех использовано
duf --sort avail # больше всех свободно


Вариант 3 (Изменить единицы измерения):

duf --bytes      # байты
duf --si # десятичные приставки (MB, GB)
duf --binary # двоичные (MiB, GiB)


Вариант 4 (Исключить определённые устройства):

duf --hide-loops       # скрыть loop-устройства (snap/docker)
duf --hide-tmpfs # скрыть tmpfs
duf --exclude /mnt/* # скрыть всё, что примонтировано в /mnt


Вариант 5 (Вывод в JSON для автоматизации):

duf --json | jq '.[] | select(.mountpoint == "/") | .size'

Получить размер корневого раздела в байтах для скрипта мониторинга.

Вариант 6 (Тема оформления):

duf --theme dark
duf --theme light

Меняет цветовую схему под ваш терминал.

Скачать бинарник с GitHub (если в репах нет):

wget https://github.com/muesli/duf/releases/download/v0.9.1/duf_0.9.1_linux_amd64.deb


Совет: добавьте в ~/.bashrc алиас alias df='duf'. Если привыкли к df, то однажды забудете, что поменяли, и будете просто радоваться красивому выводу.

P.S. Самый недооценённый флаг — `--only`. Часто `df` показывает 15 устройств, а нужны только `ext4`. `duf --only ext4` — и шума меньше, и глаза не разбегаются.


👉🏻 Я в Telegram - t.me/helcode
👉🏻 Я в VK - vk.com/helcode
👉🏻 Я на Boosty - boosty.to/helcode
👍151
dog — DNS-запросы без тонны технического мусора

dig — стандарт для DNS. Но его вывод... Это помесь из служебной информации, в котором утопает главное — ответ на ваш вопрос. dog делает то же самое, но выдаёт результат как нормальную программу: цветной, структурированный, с группировкой и без лишнего шума.

Базовое использование:

dog google.com


Вывод разбит на секции (цветные, с отступами):
- ANSWER — то, что вы искали (IP-адреса)
- AUTHORITY — кто авторитетен для этого домена
- ADDITIONAL — доп. информация (например, IP авторитетных DNS-серверов)

Вариант 1 (Запросить конкретный тип записи):

dog google.com MX      # почтовые серверы
dog google.com NS # DNS-серверы домена
dog google.com TXT # текстовые записи (SPF, DKIM, верификация)
dog google.com AAAA # IPv6-адреса
dog google.com CNAME # каноническое имя (алиас)


Вариант 2 (Краткий вывод — только IP):

dog google.com --short
# 142.250.185.46
# 142.250.185.78


Вариант 3 (Использовать конкретный DNS-сервер):

dog google.com @8.8.8.8           # Google DNS
dog google.com @1.1.1.1 # Cloudflare DNS
dog google.com @94.140.14.14 # Яндекс DNS (без фильтрации)


Вариант 4 (DNS over TLS / DNS over HTTPS):

# DNS over TLS (шифрованный, порт 853)
dog google.com --tls @1.1.1.1

# DNS over HTTPS (шифрованный через HTTP)
dog google.com --https @https://cloudflare-dns.com/dns-query


Вариант 5 (Показать только определённые поля ответа):

dog google.com --query-type A --output ip
# 142.250.185.46


Вариант 6 (Обратное DNS-резолвинг — IP в домен):

dog @8.8.8.8 -x 8.8.4.4


Главный совет: для повседневных DNS-запросов dog удобнее dig сразу после установки. Для сложных расследований с трассировкой и анализом делегирования dig всё ещё остаётся стандартом (но dog +trace закрывает 80% таких кейсов).

Пользуетесь dog или остались верны dig?

P.S. Если нужен компромисс: `dig +noall +answer example.com` — даёт чистый ответ, но флаги всё равно приходится вспоминать.
👍81🔥1
hyperfine — бенчмарк команд без боли

Ситуация: вы написали скрипт и хотите понять, быстрее ли он стал после оптимизации. Или выбираете между grep, rg и ack. Запускаете time ./script.sh несколько раз, смотрите на разброс цифр, пытаетесь усреднить в уме. Это неэффективно.

hyperfine — это утилита для бенчмаркинга команд. Она запускает команду много раз (по умолчанию 10), усредняет результат, показывает доверительный интервал и даже умеет сравнивать несколько команд между собой.

Базовое использование:

# Замерить скорость выполнения команды
hyperfine 'sleep 1'


Вывод:
Benchmark #1: sleep 1
Time (mean ± σ): 1.003 s ± 0.002 s [User: 0.002 s, System: 0.001 s]
Range (min … max): 1.000 s … 1.006 s 10 runs


Видно среднее время, стандартное отклонение (чем меньше, тем стабильнее), диапазон и количество запусков.

Вариант 1 (Сравнить две или более команд):

hyperfine 'grep -c "error" app.log' 'rg -c "error" app.log'


Вывод:
Benchmark #1: grep -c "error" app.log
Time (mean ± σ): 1.523 s ± 0.021 s
Range (min … max): 1.491 s … 1.562 s

Benchmark #2: rg -c "error" app.log
Time (mean ± σ): 0.087 s ± 0.004 s
Range (min … max): 0.081 s … 0.094 s

'rg -c "error" app.log' ran 17.51 ± 0.98 times faster than 'grep -c "error" app.log'

В конце — наглядное сравнение во сколько раз быстрее.

Вариант 2 (Настроить количество прогонов и подготовку):

# 20 прогонов, перед каждым очистить кэш диска
hyperfine --runs 20 --prepare 'sync; echo 3 | sudo tee /proc/sys/vm/drop_caches' 'cat largefile.txt'


Вариант 3 (Игнорировать первые N прогонов — для прогрева):

hyperfine --warmup 3 'node server.js'

Три первых запуска не учитываются в статистике. Нужно, чтобы кэши заполнились и JIT-компилятор успел разогнаться.

Вариант 4 (Экспорт результатов для графиков):

hyperfine --export-json results.json 'python script.py' 'pypy script.py'

# Потом можно построить график
cat results.json | jq '.results[].times'


Вариант 5 (Показать время в разных единицах):

hyperfine --style basic 'ls -l'
hyperfine --style full 'ls -l'


Вариант 6 (Сравнение с бейслайном — регрессионное тестирование):

# Сохранить результат старой версии
hyperfine --export-json old.json './script_old.py'

# Сравнить с новой
hyperfine --export-json new.json './script_new.py'
hyperfine --parameter-scan delay 1 10 -D 2 './test.sh {delay}'


Главный совет: для серьёзных замеров используйте --warmup (прогрев кэшей) и --runs 30 (много прогонов для точности). А для быстрой прикидки достаточно --runs 5.

Пользуетесь hyperfine или запускаете time десять раз подряд вручную?

P.S. Самый недооценённый режим — сравнение нескольких команд с разными аргументами через `-L`. Позволяет увидеть, как меняется производительность в зависимости от размера входных данных.

P.P.S. Ссылку прилагаю, утилита полезная: https://github.com/sharkdp/hyperfine
👍81🔥1
history - ваша память, но с фильтром

history - это команда, которую все знают, но почти никто не настраивает. Она хранит всё, что вы вводили. Включая команды с паролями, токенами и секретными ключами.

Одна ошибка - и в .bash_history лежит curl -H "Authorization: Bearer секрет_который_нельзя_показывать". Потом кто-то получает доступ к вашему терминалу или просто заглядывает через плечо.

history можно и нужно настраивать. Вот как сделать её полезной и безопасной.

Базовое использование:

# Показать историю
history

# Показать последние 20 команд
history 20

# Повторить команду номер 123
!123

# Повторить последнюю команду
!!

# Повторить последнюю команду, начинающуюся с "docker"
!docker


Вариант 1 (Не сохранять команды с пробелом в начале):

Добавьте в ~/.bashrc:
export HISTCONTROL=ignorespace


Теперь любая команда, начинающаяся с пробела, не попадёт в историю:
 curl -H "Authorization: Bearer secret" https://api.example.com


Вариант 2 (Не сохранять дубликаты подряд):

export HISTCONTROL=ignoredups


Если вы 10 раз подряд набрали ls, в истории останется только одна запись.

Вариант 3 (Не сохранять определённые команды):

export HISTIGNORE="ls:ll:cd:exit:clear:history"


Команды из списка не попадают в историю вообще.

Вариант 4 (Увеличить размер истории):

По умолчанию хранится 500-1000 команд. Можно больше:
export HISTSIZE=10000       # размер в памяти
export HISTFILESIZE=20000 # размер в файле


Вариант 5 (Добавить временные метки):

export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S  "


Теперь history показывает, когда была выполнена каждая команда:
123  2025-01-15 10:30:45  docker ps
124 2025-01-15 10:31:20 git push


Вариант 6 (Очистить историю от секретов постфактум):

# Удалить конкретную строку из файла истории
history -d 123

# Очистить всю историю
history -c


Почему это важно?

Злоумышленник, получивший доступ к вашему терминалу (или просто подглядевший через плечо), может увидеть:
- пароли в командах mysql -p, psql -U user -W
- токены доступа к облачным API
- ключи шифрования, переданные через аргументы
- внутренние адреса серверов

Настройка history занимает 2 минуты и спасает от последствий на годы.

Дополнительный совет: для действительно критичных секретов используйте переменные окружения или файлы .env, а не передавайте их в аргументах команд.

Добавьте в ~/.bashrc:
export HISTCONTROL=ignorespace
export HISTTIMEFORMAT="%F %T "
export HISTSIZE=10000
shopt -s histappend


Перезапустите терминал - и история станет безопаснее и полезнее.

А вы настраивали history или пользуетесь стандартными настройками?

P.S. Если хотите вообще отказаться от истории: `unset HISTFILE`. Но это радикально. Лучше просто исключать чувствительные команды через пробел.
👍11🔥3
atool - забудьте про флаги tar, zip и gunzip

Ситуация: вам прислали архив. Какой именно? .tar.gz? .zip? .7z? .bz2? Вы начинаете вспоминать: для tar нужны флаги -xzf, для zip - unzip, для 7z - x. И каждый раз гуглите.

atool - это обёртка над разными архиваторами. Она сама определяет тип архива и вызывает правильную команду с правильными флагами. Вместо запоминания tar -xzf file.tar.gz вы просто пишете aunpack file.tar.gz. Работает для любого формата.

Базовое использование:

# Распаковать любой архив (определяет тип автоматически)
aunpack archive.zip
aunpack archive.tar.gz
aunpack archive.7z
aunpack archive.rar

# Создать архив (сам выбирает формат по расширению)
apack archive.tar.gz file1 file2
apack archive.zip folder/


Вариант 1 (Показать содержимое архива без распаковки):

als archive.zip


Вариант 2 (Распаковать в конкретную папку):

aunpack -d /target/folder archive.tar.gz


Вариант 3 (Список поддерживаемых форматов):

atool --list


Вариант 4 (Распаковать несколько архивов сразу):

aunpack *.zip *.tar.gz *.7z


Вариант 5 (Создать архив с максимальным сжатием):

apack --best archive.7z myfolder/


Вариант 6 (Создать архив с паролем для zip):

apack --password mysecret archive.zip secret_files/


Что стоит знать о atool:

Это обёртка. Она не реализует распаковку сама, а вызывает системные утилиты: tar, unzip, 7z, unrar и другие. Если какого-то архиватора нет в системе, atool подскажет, что нужно установить.

Совет: добавьте в ~/.bashrc алиасы, если часто работаете с архивами:
alias lsar='als'
alias unarc='aunpack'
alias mkarc='apack'


P.S. Если нужно просто распаковать - `aunpack`. Если запаковать - `apack`. Если посмотреть - `als`. Запомнить три команды проще, чем флаги tar и zip.
🔥10🤝4👍2👌1
pkill и pgrep — убиваем и ищем процессы по имени

Ситуация: на сервере завис процесс, и вы не знаете его PID. Вы делаете ps aux | grep nginx, находите PID, потом kill -9 PID. Три действия, которые можно сделать одним.

pgrep находит PID по имени процесса. pkill убивает процесс по имени. Вместо трёх действий - одно.

Базовое использование:

# Найти PID процесса по имени
pgrep nginx

# Убить все процессы с именем nginx
pkill nginx

# Убить только один процесс с точным совпадением имени
pkill -x nginx


Вариант 1 (Убить процесс по полному имени):

# Не убьёт nginx, если его имя "nginx: master process"
pkill -f "nginx: master"


Вариант 2 (Убить процессы от определённого пользователя):

pkill -u user python


Вариант 3 (Убить процесс, но сначала проверить, что будет убито):

pgrep -la python
# Вывод: 1234 python script.py
# 5678 python app.py

# Потом убить
pkill python


Вариант 4 (Принудительное убийство через -9):

pkill -9 python


Вариант 5 (Искать и убивать процессы, работающие больше N часов):

# Найти процессы, работающие больше 4 часов
pgrep -l -o -t 4

# Убить их
pkill -o -t 4


Вариант 6 (Игнорировать регистр):

pkill -i nginx


Установка: pkill и pgrep есть почти везде по умолчанию (в пакете procps).

Главный совет: сначала используйте pgrep -la name, чтобы убедиться, что найдены нужные процессы. Потом pkill. На одну команду больше, но безопаснее.

P.S. Самый полезный флаг - `-f` (полное имя команды). Он находит процесс по всей командной строке, а не только по имени бинарника.
🔥6🤝21
dust - визуальный анализ диска, который работает быстрее ncdu

Ситуация: диск заполнился на 95%. ncdu показывает дерево папок, но сканирует долго. А если диск терабайтный, ждать приходится минуты.

dust (или dua) - это аналог ncdu, но написанный на Rust. Он сканирует диск быстрее, показывает те же деревья, но с более читаемым выводом и цветами.

Базовое использование:

dust


Вывод показывает список папок и файлов, отсортированный по размеру, с цветовой индикацией.

Вариант 1 (Сканировать конкретную папку):

dust /var/log


Вариант 2 (Ограничить глубину):

dust -d 3 /home

Показывает только три уровня вложенности.

Вариант 3 (Исключить определённые папки):

dust -x /home

-x - не выходить за пределы текущей файловой системы.

Вариант 4 (Вывод в процентах вместо байтов):

dust -p /var


Вариант 5 (Только папки, без файлов):

dust -f /home


Вариант 6 (Сравнить несколько папок):

dust /var/log /var/cache


Главный совет: используйте dust для быстрой первичной диагностики, когда нужно понять, какая папка жрёт место за секунды. Для глубокого анализа с удалением - ncdu всё ещё удобнее.

Пользуетесь dust или остались верны ncdu и du?

P.S. Есть ещё `dua` (Disk Usage Analyzer) - аналогичная утилита, тоже на Rust, с интерактивным режимом.
👍5🤝31
glances - мониторинг системы в реальном времени

Ситуация: на сервере что-то тормозит. Вы открываете htop - видите CPU и память. Открываете iotop - видите диск. Открываете iftop - видите сеть. Три терминала, три утилиты, глаза бегают.

glances - это единая панель, которая показывает всё сразу: CPU, память, диск, сеть, температуру, процессы, даже docker-контейнеры. И делает это в красивом интерфейсе.

Базовое использование:

glances


Вывод - экран с множеством разделов: загрузка каждого ядра CPU, использование памяти и swap, средняя нагрузка за 1, 5, 15 минут, чтение и запись на диск, входящий и исходящий сетевой трафик, топ процессов с сортировкой по любому столбцу и список Docker-контейнеров если они есть.

Вариант 1 (Включить веб-интерфейс):

glances -w


Открываете браузер, вводите http://localhost:61208 - и видите панель на удалённом сервере через браузер.

Вариант 2 (Удалённый мониторинг):

На сервере:
glances -s


На клиенте:
glances -c server_ip


Вариант 3 (Экспорт в JSON для автоматизации):

glances --export-json


Вариант 4 (Вывод только определённых данных - например, CPU и памяти):

glances --stdout cpu,mem


Вариант 5 (Мониторинг с порогами и уведомлениями):

glances --alerts


Если CPU выше 90%, память выше 80% или диск заполнен - появляется предупреждение красным цветом.

Навигация в glances:

- h — справка со всеми горячими клавишами
- q — выход
- 1 — переключить отображение CPU (все ядра или суммарно)
- 2 — переключить отображение дисков (все или только активные)
- b — переключить сортировку процессов (по CPU, памяти или I/O)
- f — показать встроенную справку по процессам

Сравнение с аналогами вкратце:

top показывает только CPU, память и процессы в базовом текстовом виде. htop делает то же самое, но цветным и интерактивным. iotop специализируется только на дисковом I/O. А glances объединяет всё это в одном экране - и CPU, и память, и диск, и сеть, и Docker, и температуру.

Главный совет: запомните флаг -w - веб-интерфейс. Один раз запустили на сервере и забыли. Мониторинг всегда доступен.

Пользуетесь glances или предпочитаете собирать информацию по частям из разных утилит?

P.S. `glances` можно запустить как демон (`glances -d`) и настроить отправку метрик в InfluxDB или другие системы мониторинга.
👍11🔥21🤔1
diff - покажи мне разницу

Ситуация: у вас есть два похожих файла конфигурации. Или два лога с одного сервера за разные дни. Или две версии одного скрипта. Вам нужно понять, что именно изменилось, а не просто знать, что они разные.

diff - это утилита, которая построчно сравнивает два файла и показывает, что добавилось, удалилось или изменилось. Без неё сравнивать файлы глазами - занятие для самых терпеливых.

Базовое использование:

diff file1.txt file2.txt


Вывод показывает:
- строки, которые есть только в первом файле (помечены <)
- строки, которые есть только во втором файле (помечены >)
- номера строк, где есть различия

Вариант 1 (Сравнить две папки рекурсивно):

diff -r dir1/ dir2/


Показывает, какие файлы добавились, удалились или изменились в папках.

Вариант 2 (Игнорировать пробелы и табуляции):

diff -w file1.txt file2.txt


Полезно, когда разница только в форматировании.

Вариант 3 (Показать только имена файлов, без содержимого):

diff -q -r dir1/ dir2/


Вариант 4 (Выдать результат в унифицированном формате):

diff -u file1.txt file2.txt


Унифицированный формат (тот, что показывает Git) - компактный и читаемый. Строки с - удалены, с + добавлены.

Вариант 5 (Сравнить, игнорируя регистр букв):

diff -i file1.txt file2.txt


Вариант 6 (Выдать результат для патча - можно применить позже):

diff -u file1.txt file2.txt > changes.diff


Созданный файл можно применить через patch:
patch file1.txt < changes.diff


Возможное применение #1 (сравнение конфигов до и после изменений):

diff -u /etc/nginx/nginx.conf.bak /etc/nginx/nginx.conf


Сразу видно, какие строки добавили, какие убрали. Никаких "а что тут было раньше?".

Возможное применение #2 (проверка, изменился ли код после рефакторинга):

diff -r old_version/ new_version/ | grep "\.py"


Показывает только изменения в Python-файлах. Остальное игнорируем.

Главный совет: всегда используйте diff -u для унифицированного вывода. Он понятнее, компактнее и совместим с патчами.

Пользуетесь diff для сравнения файлов или открываете их в редакторе рядом и сравниваете глазами?

P.S. Если нужно сравнить содержимое папок с исключением определённых файлов (например, .git, __pycache__): `diff -r -x .git -x __pycache__ dir1/ dir2/`.
👍9