среда, 15 января 2020 г.

Удалить неиспользуемые ядра и очистить систему в автоматическом режиме (выбор действия по сценарию)

Идея: создать сценарий (скрипт на bash), по результатам выполнения которого определялась бы необходимость осуществления операции удаления неиспользуемых в системе ядер с последующей очисткой системы от ненужных пакетов.

Примечание. Для Linux Mint 20 и выше смотрите здесь.

В отличие от Windows, Linux обладает меньшей "замусоренностью", но и он, с точки зрения перфекционализма, нуждается в периодической чистке. Пример освобождения системы от ненужных файлов читайте здесь. Что же касается ядер, то при установке новых ядер старые ядра не удаляются и, накапливаясь вместе с сопутствующими модулями (см. каталог /lib/modules), начинают занимать место, которое со временем может достигать солидных значений.

У одного из моих знакомых пользователей Linux таких ядер к настоящему времени уже имеется 17 шт. Ради любопытства мной была предпринята попытка подсчёта примерного суммарного места, занимаемого текущим ядром с сопутствующими ему модулями. Вышло 305,9 Мб. Экстраполируя данное значение на 17 неиспользуемых ядер, получается порядка 5-5,1 Гигабайт дискового пространства, выключенного из полезной деятельности.



Сценарий удаления неиспользуемых ядер

Необходимость осуществления заявленных действий будет определяться по результату подсчёта имеющихся в системе ядер. Подсчёт будет вестись по файлам, расположенным в каталоге /boot, имена которых относятся к той или иной версии ядра. К таким файлам относятся config* , initrd.img* , vmlinuz* .  В рассматриваемом примере подсчёт ведётся по файлам vmlinuz* .

Примечание. Следует иметь в виду, что удалению подлежат все ядра кроме используемого системой в настоящее время (то есть на момент выполнения сценария). Если имеется необходимость сохранения предыдущего ядра, то воспользуйтесь примерами команд, изложенными в этой публикации.

Если будет обнаружено, что число ядер больше 1, то будет выполнена команда удаления всех предыдущих ядер. Если будет обнаружено, что число ядер равно 1, то никаких действий предпринято не будет.

Сценарий оформляется как исполняемый файл sh

#!/bin/bash
a=`find /boot -name vmlinuz* | wc -l`
b=1
if [ $a -gt $b ];
  then
  apt purge -y $(dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d' | head -n -1)
 else
  :
fi
exit

Примечание: двоеточие соответствует команде "ничего не делать".

Поскольку выполняемые действия требуют полномочий суперпользователя, а выполнять созданный скрипт sh планируется от имени текущего пользователя системы, то в файл /etc/sudoers необходимо внести запись, разрешающую его выполнение (sudo clean.sh) без запроса ввода пароля. Откройте файл в текстовом редакторе, например:

sudo xed /etc/sudoers  или  sudo gedit /etc/sudoers

и внесите строку

имя_текущего_пользователя ALL=NOPASSWD: путь_к_скрипту

Сохраните внесённые изменения и перезагрузите систему. Если вдруг вами была допущена ошибка синтаксиса файл sudoers, то выполните действия, описанные здесь.

В своей системе мной была внесена строка

minter ALL=NOPASSWD: /home/minter/Tools/scripts/clean.sh


Объединение удаления ядер и очистки системы

В своей системе было принято решение об объединении процедур удаления неиспользуемых ядер и автоочистки системы от ненужных файлов в один сценарий. Результаты выполнения заносятся в краткий протокол.

#!/bin/bash
day=`date '+%m.%d'`
a=`find /boot -name vmlinuz* | wc -l`
b=1
log=/home/minter/Reports/system/$day.clean.txt
if [ $a -gt $b ];
 then
  time=`date '+%H-%M-%S'`
  echo "$time -- ядер в системе – $a, запуск удаления ядер." >> $log
  apt purge -y $(dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d' | head -n -1)
  sleep 5
  time=`date '+%H-%M-%S'`
  echo "$time -- запуск автоочистки." >> $log
  apt autoclean
  sleep 5
  time=`date '+%H-%M-%S'`
  echo "$time -- запуск автоудаления." >> $log
  apt autoremove -y
else
  time=`date '+%H-%M-%S'`
  echo "$time -- очистка системы не требуется." >> $log
fi
exit

Так как мой компьютер постоянно включён в определённый промежуток времени, то сценарий будет выполняться по пользовательскому заданию cron (у меня – раз в месяц). Если у Вас компьютер включается по случайному выбору временного промежутка, то выполнение сценария имеет смысл или включить в атозагрузку системы, или выполнять вручную, создав соответствующий значок (кнопку) запуска. При использовании пользовательского задания cron команда на выполнение должна быть sudo путь_к_скрипту.

При использовании задания cron данное задание можно оформить как запускаемое от имени root, запустив редактор sudo crontab -e  При этом нет необходимости вносить изменения в файл /etc/sudoers  Однако в этой публикации, в первую очередь, рассматривается возможность выполнения заявленных действий в рамках полномочий обычного пользователя.

Работа сценария была проверена на 3 системах Linux Mint версий 18.3 и 19.3

вторник, 14 января 2020 г.

Выключить компьютер после выполнения задания через cron


Возникла необходимость автоматизировать процесс создания резервных копий важных данных с последующим выключением компьютера.

Создание резервных копий производится через сценарий sh с использованием ПО rclone, запуск которого задаётся через пользовательское задание cron.

Но простым включением в сценарий команды shutdown или shutdown -h now желаемый результат не достигается (подробности здесь). Команда выключения /sbin/poweoff должна быть выполнена под правами суперпользователя, что влечёт за собой команду sudo и сопутствующий ей ввод пароля для повышения полномочий пользователя в системе.

Поэтому для реализации этой задумки необходимо сделать следующее:

1) Разрешить пользователю системы, от имени которого будет запущено задание cron, выполнять команду sudo /sbin/poweroff без ввода пароля;

2) добавить в конец сценария на bash команду sudo /sbin/poweroff

Чтобы выполнить команду sudo /sbin/poweroff без ввода пароля необходимо внести изменения в файл /etc/sudoers

sudo xed /etc/sudoers (или sudo gedit /etc/sudoers)

Вписать строку  имя_пользователя ALL=NOPASSWD: /sbin/poweroff  Чтобы изменения вступили в силу перезагрузите систему.

Имя_пользователя, под которым Вы работаете в системе (если до сих пор его не знаете) можно посмотреть, запустив терминал. Например, в моём случае имя пользователя minter, поэтому строка принимает значение:

minter ALL=NOPASSWD: /sbin/poweroff

Если обнаружите, что после внесённых изменений файл sudoers оказался "испорчен", то выполните действия, описанные в этой публикации.

Ниже приводится пример сценария (скрипта на bash), запускаемого через cron, в ходе которого после 5 последовательно выполняемых заданий по резервированию данных через rclone через 5 секунд следует выключение компьютера.

#!/bin/bash
do=/home/minter/Tools/scripts/rclone
$do/books.sh
$do/sa.sh
$do/ca.sh
$do/cur.sh
$do/sys.sh
sleep 5
sudo /sbin/poweroff


суббота, 11 января 2020 г.

Пропал звук: не работает alsa. Вариант решения частной проблемы

Новый 2020 год принёс "подарок". Собственно говоря, при попытке запустить на воспроизведение файл mp3 звука нет.


Поиск в Интернет по решению данной проблемы напоминает "сизифов труд". Можно бесконечно читать различные ветки обсуждения по попыткам решить проблему, но до конкретного результата так и не дойти. Вообще-то, в большинстве случаев проблема решается простой перезагрузкой системы, но не всегда.

Не скажу, что описанное ниже решение универсальное, но попробовать можно.

Было замечено, что звук возвращается после выполнения команды alsactl init и последующей перезагрузке системы:


Однако при дальнейшем "расследовании" было выяснено, что система определяла наличие двух звуковых устройств, второе из которых представляло собой подключенную через USB веб-камеру со встроенным в неё микрофоном. Когда-то она была подключена, но потом про этот факт было "успешно" забыто.
 
Кстати говоря, полезной командой для сохранения настройки alsactl является

sudo alsactl store

На ресурсе https://archlinux.org.ru/forum/topic/15179 было найдено решение для наличия в системе одновременно нескольких звуковых устройств. Выполняется две команды терминала и по результатам вывода результатов в домашнем каталоге создаётся файл  .asoundrc  в содержании которого указывается "желаемое" звуковое устройство.

Конкретно в моём случае:

cat /proc/asound/modules

0 snd_hda_intel
1 snd_usb_audio

cat /proc/asound/cards

0 [PCH ]: HDA-Intel - HDA Intel PCH
HDA Intel PCH at 0xfbff4000 irq 29
1 [U0x46d0x825 ]: USB-Audio - USB Device 0x46d:0x825
USB Device 0x46d:0x825 at usb-0000:00:1d.0-1.4, high speed

Содержание файла  .asoundrc :

pcm.!default {
type hw
card 0
}

ctl.!default {
type hw
card 0
}

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

P.S. Подобная ситуация произошла после просмотра online видео на ok.ru