ServerAdmin.ru
31.6K subscribers
853 photos
57 videos
23 files
3K links
Авторская информация о системном администрировании.

Информация о рекламе: @srv_admin_reklama_bot
Автор: @zeroxzed

Второй канал: @srv_admin_live
Сайт: serveradmin.ru

Ресурс включён в перечень Роскомнадзора
Download Telegram
​​Почти во всех популярных дистрибутивах Linux в составе присутствует утилита vmstat. С её помощью можно узнать подробную информацию по использованию оперативной памяти, cpu и дисках. Лично я её не люблю, потому что вывод неинформативен. Утилита больше для какой-то глубокой диагностики или мониторинга, нежели простого использования в консоли.

Если есть возможность установить дополнительный пакет, то я предпочту dstat. Там и вывод более наглядный, и ключей больше. А информацию по базовому отображению памяти хорошо перекрывает утилита free.

Тем не менее, если хочется быстро посмотреть некоторую системную информацию, то можно воспользоваться vmstat. У неё есть возможность выводить с определённым интервалом информацию в консоль. Иногда для быстрой отладки это может быть полезно. Запускать лучше сразу с парой дополнительных ключей для вывода информации в мегабайтах и с более широкой таблицей:

# vmstat 1 -w -S M

Как можно убедиться, вывод такой себе. Сокращения, как по мне, выбраны неудачно и неинтуитивно. В том же dstat такой проблемы нет. Но в целом привыкнуть можно. В man vmstat они подробно описаны, так что с интерпретацией проблем не должно возникать.

А вообще, эта заметка была написана, чтобы в неё тиснуть необычный однострочник для bash, который меня поразил своей сложностью и непонятностью, но при этом он рабочий. Увидел его в комментариях на хабре и сохранил. Он сравнивает вывод информации об использовании памяти утилиты free и cat /proc/meminfo:

# eval $(free -kw | awk '/Mem/{print "mtotal="$2"\nmused="$3"\nmfree="$4"\nmshared="$5"\nmbuffers="$6"\nmcache="$7"\nmavailable="$8}/Swap/{print "stotal="$2"\nsused="$3"\nsfree="$4}');eval $(awk -F'(: +)| ' '!/\(/{print $1"="$2}' /proc/meminfo);clear; echo -e ";;;;;\nMem;total;$mtotal;│;$MemTotal;MemTotal\nMem;used;$mused;│;$[MemTotal-MemFree-Buffers-Cached-KReclaimable];MemTotal-MemFree-Buffers-Cached-KReclaimable\nMem;free;$mfree;│;$MemFree;MemFree\nMem;shared;$mshared;│;$Shmem;Shmem\nMem;buffers;$mbuffers;│;$Buffers;Buffers\nMem;cache;$mcache;│;$[Cached+KReclaimable];Cached+KReclaimable\nMem;available;$mavailable;│;$MemAvailable;MemAvailable\nSwap;total;$stotal;│;$SwapTotal;SwapTotal\nSwap;used;$sused;│;$[SwapTotal-SwapFree];SwapTotal-SwapFree\nSwap;free;$sfree;│;$SwapFree;SwapFree\n\n" | column -t -s ";" --table-columns " ,free -kw¹,KiB¹, ,KiB²,/proc/meminfo²" --table-right "free -kw¹,KiB¹" --table-truncate "/proc/meminfo²"

Это прям какой-то царь-однострочник. Я когда его первый раз запускал, не верил, что он заработает. Но он заработал. В принципе, можно сохранить и использовать.

В завершении дам ссылку на свою заметку с небольшой инструкцией, как и чем быстро в консоли провести диагностику сервера, если он тормозит. Обратите внимание там в комментариях на вот этот. Его имеет смысл сохранить к себе.

#bash #script #perfomance
👍82👎3
​​Недавно, когда вырезал из дампа mysql содержимое одной таблицы с помощью sed, подумал, что неплохо было бы сделать подборочку с наиболее актуальными и прикладными примерами с sed.

Уже когда начал её составлять вдруг подумал, а нужно ли сейчас вообще всё это? Как считаете? Мы находимся на сломе эпох. Сейчас же ChatGPT сходу приводит все эти команды и практически не ошибается в типовых задачах. Я до сих пор так и не начал им пользоваться. Пробовал несколько раз, но постоянно не использую. По привычке ищу решение в своих записях, чаще всего тут на канале.

Брюзжать, как старый дед, на тему того, что надо своими мозгами думать, а то совсем захиреют, не буду. ИИ помощники это уже наше настоящее и 100% наше будущее, как сейчас калькуляторы. Надо начинать осваивать инструментарий и активно использовать. Ну а пока вернёмся к sed 😁

🟢 Вырезаем всё, что между указанными строками в файле:

# sed -i.back '22826,26719 d' dump.sql

🟢 Вырезать первую и последнюю строки. Часто нужно, когда отправляешь в мониторинг вывод каких-нибудь консольных команд. Там обычно в начале какие-то заголовки столбцов идут, а в конце тоже служебная информация:

# sed -i.back '1d;$d' filename

🟢 Заменить в файле слово old_function на new_function:

# sed -i.back 's/old_function/new_function/g' filename

🟢 Если нужен более гибкий вариант поиска нужного слова, то можно использовать регулярные выражения:

# sed -i.back -r 's/old_function.*?/new_function/g' filename
# sed -i.back -r 's/^post_max_size =.*/post_max_size = 32M/g' php.ini

🟢 Удаляем комментарии и пустые строки:

# sed -i.back '/^;\|^$\|^#/d' php.ini

🟢 Вывести записи в логе веб сервера в интервале 10.01.2024 15:20 - 16:20. Удобная штука, рекомендую сохранить.

# sed -n '/10\/Jan\/2024:15:20/,/10\/Jan\/2024:16:20/p' access.log

🟢 Добавить после каждой строки ещё одну пустую. Иногда нужно, чтобы нагляднее текст оценить. Второй пример - добавление пустой строки после найденного слова в строке:

# sed -i.back G filename
# sed -i.back '/pattern/G' filename

Про sed можно писать бесконечно, но лично я что-то более сложное редко использую, а вот эти простые конструкции постоянно. Чаще всего именно они используются в связке с другими консольными утилитами.

#bash #sed
👍127👎2
​​Расскажу об одной возможности bash, с которой хоть и не часто, но приходится сталкиваться. Я столкнулся, когда писал утреннюю заметку про qemu-guest-agent. С его помощью можно выполнить любую команду на гостевой системе. Например так:

# qm guest exec 101 "df"

Далее мне захотелось добавить некоторые ключи к этой команде:

# qm guest exec 101 "df -Th"
Agent error: Guest agent command failed, error was 'Failed to execute child process “df -Th” (No such file or directory)'

Получил ошибку. Эта команда так не работает. Агент пытается найти бинарник df -Th. Читаю описание команды. Дополнительные аргументы надо передавать отдельно, примерно так:

# qm guest exec 101 "df" "/"

В таком виде работает. Добавляю ключи к df и опять ошибка:

# qm guest exec 101 "df" "/" "-Th"
Unknown option: th
400 unable to parse option

Тут типичная проблема для bash. Команда qm считает, что в конструкции -Th я передаю параметры для неё, а она их не понимает. Как же быть? Для этого существуют два тире --. Они говорят команде, что после них нужно игнорировать любые аргументы. То есть правильно будет вот так:

# qm guest exec 101 "df" "/" -- "-Th"

В таком виде команда отработает так, как ожидается. Двойным тире мы дали понять qm, что -Th не её аргументы.

С подобной проблемой легко столкнуться, когда, к примеру, вам через grep нужно найти строку -v. Как её указать? Это очень наглядный пример по данной теме. Grep будет считать, что -v это её аргумент и вместо поиска будет выводить свою версию. Тут надо действовать аналогично:

# grep -- -v file.txt

-- нужны, когда какая-то строка начинается с тире -, реже с +, но при этом не является аргументом команды, и нам нужно дать ей понять это.

#bash
👍176👎5
​​Если вам необходимо кому-то передать свой bash скрипт, но при этом вы не хотите, чтобы этот кто-то видел его содержимое, то есть простое решение. С помощью утилиты shc его можно транслировать в язык C и скомпилировать. На выходе будет обычный бинарник, который будет успешно работать практически на любой ОС Linux.

Это может быть актуально, если вы делаете кому-то что-то на заказ и надо продемонстрировать работоспособность решения. Если сразу отдать скрипт, то недобросовестные заказчики могут не заплатить, так как всё решение это и есть текст скрипта. Возможно, вы просто захотите от кого-то скрыть чувствительные данные или идею реализации той или иной функциональности.

Shc живёт в базовых репозиториях Debian или Ubuntu, возможно и в других дистрибутивах. Для сборки также понадобится пакет gcc.

# apt install shc gcc

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

#!/bin/bash
v=$1
echo "Simple BASH script. Entered VARIABLE: $v"

Запускаем:

# ./script.sh 111
Simple BASH script. Entered VARIABLE: 111

Теперь компилируем его в бинарник:

# shc -f -r script.sh

На выходе получаем два файла:
- script.sh.x - бинарник
- script.sh.x.c - исходный код

Запускаем бинарь:

# ./script.sh.x 123
Simple BASH script. Entered VARIABLE: 123

Отработал точно так же, как и bash скрипт. С помощью shc можно указать дату, после которой скрипт запускаться не будет. Выглядит это примерно так:

# shc -e 31/12/2023 -m "Извини, но ты опоздал!" -f -r script.sh
# ./script.sh.x
./script.sh.x: has expired!
Извини, но ты опоздал!

Я подозреваю, что прятать какие-то важные пароли таким образом опасно. Наверняка есть способ, чтобы его вытащить оттуда. Мне даже кажется, что это и не слишком сложно. В памяти то всё равно содержимое будет в каком-то виде отображаться. Можно сдампить память в момент запуска и посмотреть.

Быстро поискал и нашёл готовое решение по расшифровке таких файлов:
https://github.com/yanncam/UnSHc
Так что имейте ввиду, что это в основном защита от дурака.

#bash #script
👍186👎4
​​Вчера заметка про простенький http сервер на python породила интересное обсуждение на тему передачи файлов. Конечно, способов существует уйма, и каждый использует то, что ему привычнее, удобнее, быстрее.

Лично у меня прижились следующие способы передачи.

🟢 Если надо перекинуть один файл между серверами, я использую scp:
# scp -P 22777 user@10.1.4.4:/mnt/data/BackUp/onlyoffice.tar.gz /backup
Сразу привёл пример с нестандартным портом, там как тут используется заглавная -P. Я долго не мог запомнить это, используя маленькую -p, как в ssh.

🟢 Если файлов много, использую rsync:
# rsync -avz -e "ssh -p 1234 -i /root/.ssh/id_rsa" user@10.1.4.22:/data/mail /data
Тоже такой универсальный пример, где сразу и порт, и ключ указан, если аутентификация не по паролю.

🟢 А вот если надо скопировать что-то разово на мой рабочий ноут или какой-то виндовый комп, то я запускаю веб сервер на python и просто скачиваю. Для текстовых логов актуально, чтобы сразу забрать все, что нужны:
# cd /var/log
# python3 -m http.server 8000

🔴 А вот простой трюк, когда надо перекинуть файл с одного сервера на другой, но при этом подключение между серверами не настроено, но я со своего ноута или jump сервера могу подключиться к обоим. Тогда можно сделать вот так:
# ssh user01@10.1.4.4 'cat /home/user01/file.tar.gz' | ssh user02@10.1.5.10 'cat > /home/user02/file.tar.gz'

#bash
👍177👎1