среда, 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


четверг, 12 декабря 2019 г.

Дозапись выделенного фрагмента текста в файл через bash


Описываемое решение создавалось для личных нужд и является модификацией кода, изложенного в публикации "Сохранить выделенный текст в файл через скрипт bash".

После выделения фрагмента текста вызывается запуск сценария, который осуществляет дозапись этого фрагмента в текстовый файл. Затем содержимое текстового файл подвергается дальнейшей обработке, в описываемом случае – преобразованию в файл odt и последующим открытием файла odt для редактирования. При этом исходный файл txt удаляется.

Примечание. Для преобразования в odt используется пакет wordgrinder

По реализации операции разделены на 2 сценария: сбор информации и окончательное оформление целевой заметки в файле odt.

Первый сценарий:

#!/bin/bash
out="/tmp/notes.$$"
name="$HOME/RClone/text.txt" # файл, в который будут дописываться заметки
xclip -o | zenity --width=600 --height=300 --title  "Текст заметки" --text-info --editable > "$out"
cat "$out" >> "$name"
rm "$out"
exit

Второй сценарий:

#!/bin/bash
place=$HOME/RClone
wordgrinder -c $place/text.txt $place/text.odt
day=`date '+%j'`  #  день по счёту от начала года (1 января соответствует 001)
date=`date '+%m-%d'`  # дата "месяц-день"
time=`date '+%H-%M'`  # время "часов-минут"
mv $place/text.odt $place/$date.Заметки.No.$day.$time.odt
rm $place/text.txt
xdg-open $place/$date.Заметки.No.$day.$time.odt
exit  

Как заключительная часть, производится резервирование файла odt (резервная копия) на одно из облачных хранилищ. Операция выполняется по пользовательскому расписанию cron программным решением rclone.


среда, 4 декабря 2019 г.

Не работает команда меню "Открыть папку назначения" клиента qBittorrent в Linux Mint xfce


В Linux Mint 19.2 xfce, используемой мной на одном из компьютеров, было замечено, что при вызове команды правого контекстного меню "Открыть папку назначения" торрент-клиента qBittorrent ничего не происходит.


Бывает, что выполнение такой команды является необходимым.

После того как было обнаружено, что настройки шрифтов и их размера расположены не в настройках самого qBittorrent, а в настройках Qt5, было решено предпринять попытку "обмануть" qBittorrent. По большому счёту, приложения Qt разрабатываются для графического окружения KDE, в то время как для xfce "родными" являются приложения на GTK. Для графического окружения KDE по умолчанию предлагается менеджер файлов dolphin.

Исходя из описанного выше, в скрытый файл .bashrc была внесена команда, при которой файловому менеджеру dolphin сопоставляется файловый менеджер по умолчанию, то есть thunar:

alias dolphin='exo-open --launch FileManager %F'


В результате по команде "Открыть папку назначения" у меня стал запускаться менеджер файлов thunar:



понедельник, 2 декабря 2019 г.

Запуск приватного окна Chrome через bash

По аналогии с запуском приватного окна браузера Opera было принято решение попробовать таким же образом запускать и браузер Chrome. Однако, как говорится в поговорке, вот тебе, бабушка и Юрьев день!

~ $ chrome -private
chrome: команда не найдена

Во-первых, правильной командой браузера Chrome является google-chrome-stable (имеется в виду, что используется стабильная версия релиза).

Примечание. Найденный совет на askubuntu мне не подошёл, так как в выводе терминала было указано:  

Please launch slimjet via the wrapper script: flashpeak-slimjet

Возможно потому, что у меня имеется ещё браузер Slimjet.

Во-вторых, – в браузере Chrome приватное окно называется "режим инкогнито".

Исходя из вышесказанного, команда для запуска 1 приватного окна будет:

google-chrome-stable -incognito

Чтобы запустить несколько окон с подстановкой адресов сайтов укажите после incognito желаемые адреса, например:

google-chrome-stable -incognito mail.ru yandex.ru

Соответственно, сценарий (скрипт на bash) будет иметь вид:

#!/bin/bash
google-chrome-stable -incognito mail.ru yandex.ru &
exit

Примечание. Как указывалось в предыдущих публикациях, cимвол & означает, что этот сценарий (скрипт sh) не будет ожидать завершения работы запущенного экземпляра браузера Firefox и будет завершён сразу же после выполнения команды google-chrome -incognito  Соответственно, относящиеся к задаче процессы sh будут выгружены из системы, не занимая в ней ресурсов.

Любопытно, что в отличие от аналогичного запуска в браузере Opera, фокус автоматически устанавливается на первом окне.


Аналогичные решения для Firefox, Opera  


воскресенье, 1 декабря 2019 г.

Запуск приватного окна Opera через bash


Как и в случае с запуском приватного окна в Firefox, возникла необходимость в запуске приватных окон браузера Opera через bash (в моём случае через скирпт sh).

Несмотря на аналогичный ключ запуска приватного окна - private, в командах имеются особенности.

В приводимых примерах запуск приватного окна сопровождается указанием конкретного адреса веб-ресурса.

Запуск единичного окна:

#!/bin/bash
/usr/bin/opera -private mail.ru &
exit

или

#!/bin/bash
opera -private mail.ru &
exit

Символ & означает, что этот сценарий (скрипт sh) не будет ожидать завершения работы запущенного экземпляра браузера Opera и будет завершён сразу же после выполнения команды opera -private  Соответственно, относящиеся к задаче процессы sh будут выгружены из системы, не занимая в ней ресурсов.

Однако при необходимости запуска двух окон команда, которая работает в Firefox, открывает не 2 вкладки, а 2 экземпляра браузера Opera:

#!/bin/bash
opera -private mail.ru &
opera -private mail.yandex.ru &
exit


Чтобы открыть именно 2 вкладки необходимо сделать так:

#!/bin/bash
opera -private mail.yandex.ru mail.ru &
exit


Интересно, что фокус автоматически устанавливается на втором окне, а не на первом.

Аналогичные решения для Firefox, Chrome