пятница, 9 декабря 2022 г.

Уменьшение размера крупных скринсшотов, с сохранением читаемости текста страницы

 convert '61444x4608.png' -define filter:support=2 -unsharp 0.25x0.08+8.3+0.045 -dither None -posterize 136 -quality 82 -define jpeg:fancy-upsampling=off -define png:compression-filter=5 -define png:compression-level=9 -define png:compression-strategy=1 -define png:exclude-chunk=all -interlace none -colorspace sRGB  '600x400.jpg'

четверг, 7 мая 2020 г.

Комментарий к вопросу о возможности восстановления DVDR, показался интересным, этот теоретический пост про технологию изготовления дисков, что привожу его здесь в машинном переводе с английского:

Дальше »

понедельник, 25 февраля 2019 г.

linux: бесконечный своп...

В какой-то момент заметил, что дистрибутив linux (не важно какой именно) слишком легко сваливается в своп: постоянно что-то безостановочно пишет на HDD... Посмотрев количество свободной памяти, обнаружил, что практически вся память отдана в buff/cache и никак не используется, в то же время, когда рабочая память всего 700мб... Как перераспределить память ? На форуме Убунты нашёл такой рецепт:

в /etc/sysctl.conf
vm.swappiness=05
vm.laptop_mode=5
vm.dirty_writeback_centisecs=6000
vm.vfs_cache_pressure=1000
Перечёркнутая строка нужна, это если только есть лаптоп

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

На toster.ru есть ещё опции, но, пока, этого достаточно

UPD: А на хабре нашёл заметку: https://habr.com/ru/post/344836/#comment_10569644

пятница, 21 декабря 2018 г.

Алгебраические операции на bash

На примере программы "Подсчет числа дней между двумя датами"
Дальше »

пятница, 30 ноября 2018 г.

cd проверка статуса лотка привода

К сожалению, чистый bash не имеет возможности проверять открыт-ли лоток привода или нет, но это можно сделать 3 способами:

1. С помощью lshw
lshw -quiet 2>/dev/null | awk '/\*-cd/,/con/' | sed -e 's/^[ \t]*//' | grep configuration | cut -d ' ' -f3
2. С помощью крошечной программы trayopen
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <fcntl.h> // for open
#include <unistd.h> // for close
#include <linux/cdrom.h>

int main(int argc,char **argv) {
  int cdrom;
  int status=1;

  printf("Usage: trayopen [device]\n");
  printf("Result: Open tray exit code 0, closed tray exit code 1.\n");

  if ((cdrom = open(argv[1],O_RDONLY | O_NONBLOCK)) < 0) {
    printf("Unable to open device %s. Provide a device name (/dev/sr0, /dev/cdrom) as a parameter.\n",argv[1]);
    exit(1);
  }

  if (ioctl(cdrom,CDROM_DRIVE_STATUS) == CDS_TRAY_OPEN) {
    status=0;
  }

  close(cdrom);
  exit(status);
}
Компиляция: gcc trayopen.c -o trayopen .
В найденной в сети программе trayopen не хватало строки
#include <unistd.h> // for close
И при компиляции без этой строки выводило:
implicit declaration of function «close»; did you mean «pclose»? [-Wimplicit-function-declaration]

Использовать программу можно через операции сравнения:
 ./trayopen /dev/sr0 && echo tray is open || echo tray is closed
3. Через программу cdstatus:
#include <sys/ioctl.h>
#include <linux/cdrom.h>
#include <fcntl.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <poll.h>
int main(int argc, char **argv){
        int fd, s; int pt = -1;
        if(argc < 2)
                errx(1, "usage: %s /dev/srX [poll_secs] [verbose]", argv[0]);
        if((fd = open(argv[1], O_RDONLY|O_NONBLOCK)) == -1)
                err(1, "open %s", argv[1]);
        if(argc > 2 && ((pt = strtod(argv[2], 0) * 1000) < 1 || pt > 3600000))
                errx(1, "bad timeout '%s'", argv[2]);
redo:
        switch(s = ioctl(fd, CDROM_DRIVE_STATUS, 0)){
        case -1: err(1, "ioctl(CDROM_DRIVE_STATUS)");
        case CDS_NO_INFO: errx(1, "ioctl(CDROM_DRIVE_STATUS) not implemented");
        }
        if(pt < 0 || argc > 3)
                switch(s){
                case CDS_NO_DISC: printf("no_disc\n"); break;
                case CDS_TRAY_OPEN: printf("tray_open\n"); break;
                case CDS_DRIVE_NOT_READY: printf("drive_not_ready\n"); break;
                case CDS_DISC_OK: printf("disc_ok\n"); break;
                default: printf("status=%d\n", s); break;
                }
        if(pt > 0 && s != CDS_DISC_OK){
                if(poll(0, 0, pt) < 0) err(1, "poll");
                goto redo;
        }
        return s != CDS_DISC_OK;
}
cdstatus выводит результат не в true, а собственно в текстовый вывод: "no_disc", "tray_open", "drive_not_ready", "disc_ok".

 Спасибо авторам идей и тем на форумах:
Detect CD tray status 
problem using ioctl , CDROM_DRIVE_STATUS
Implicit declaration of function ‘close'

пятница, 5 октября 2018 г.

Циклы в sed

Машинный перевод комментария из англоязычного интернета:

sed ':a;N;$!ba;s/\n/ /g' file

прочитает весь файл в цикле, а затем заменит новую строку (строки) пробелом.

Объяснение:

1. Создайте ярлык через :a .
2. Добавьте текущую и следующую строку в пространство шаблонов через N
3. Если мы находимся до последней строки, переходим к созданной метке $!ba ( $! Означает не делать ее на последней строке, так как должна быть одна последняя новая строка).
4. Наконец, подстановка заменяет каждую новую строку пробелом в пространстве шаблонов (это весь файл).

link

суббота, 11 августа 2018 г.

Копирование с преобразованием...

Иногда возникает необходимость перекладывать файлы с каким-либо преобразованием, но на новом месте иметь такие же названия папок, как и в предыдущем, можно, конечно, вручную, в каждой папке конвертировать с указанием нового места, но можно и автоматизировать:
$ IFS=$'\n' ; for i in $( find . -name "*.mp4" ) ; do destfolder=~/aac ; namefolder=$( dirname $i ) ; if [[ ! -d $destfolder/$namefolder ]] ; then mkdir -p $destfolder/$namefolder ; fi ; ffmpeg -i $i -map_metadata 0 -vn -acodec copy $destfolder/$namefolder/$i.m4a ; done
Или, к примеру, синхронизация:
IFS=$'\n' ; for i in $( find . -iname "*menu.lst" ) ; do destfolder=grub4dos_menu/ ; namefolder=$( dirname $i ) ; if [[ ! -d $destfolder/$namefolder ]] ; then mkdir -p $destfolder/$namefolder ; fi ;  cp $i  $destfolder/$namefolder ; done
То есть аналог команды rsync -va ./sourcefolder ./destfolder

Обратите внимание на логический операнд -d - условие верно если $destfolder/$namefolder уже имеется  и является папкой, если вместо -d вы используете -z то будет создаваться лишняя (пустая папка). Установка переменной IFS нужна чтобы правильно обрабатывать пробелы в именах файлов и папок. Оператор -map_metadata 0 для ffmpeg в первом примере нужен для переноса тегов из источника в результат.