Толик Панков
hex_laden
............ .................. ................
Page Summary

November 2020
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30

Back Viewing 0 - 20  
Посмотреть размер каталога в Linux. В консоли, но интерактивно и наглядно (ncdu).

И наглядно увидеть, где засрано :)

Для отображения размеров каталогов (с подкаталогами), есть стнадартная утилита du, но, если честно, она не очень удобная. Гораздо удобнее ее аналог, написанный с помощью ncurses - ncdu

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

ncdu

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


Сканирование

В подкаталоги входить можно по ENTER, возврат назад по стрелке влево, клавише h или < (обычно запятая с шифтом) или по нажатию ENTER на .., как в mc. Краткая справка по ? (не забывайте нажать SHIFT), выход по q.


Отображение каталогов и их размеров


В Slackware устанавливается штатным образом через sbopkg, как в других линуксах не знаю, в Убунте и Дебиане есть в репозиториях.

Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2020/02/18/posmotret-razmer-kataloga-v-linux-v-konsoli-no-interaktivno-i-naglyadno-ncdu/

Linux wget, коды возврата/завершения. Коды ошибок wget.

Раз уж пошел разговор про wget (копия), решил я заодно дополнить добрым людям скрипт какими-нибудь осмысленными сообщениями об ошибках, а для того нужны коды завершения.

Кто-то, неизвестно почему, утверждал, что в man их нет. Есть. Но пусть уж будут и тут, и мне от склероза, и мало ли кому другому, кто не любит на буржуйском читать.

Коды завершения wget


0 - OK (ошибок нет)
1 - Иная / общая ошибка (generic error code)
2 - Ошибка в параметрах командной строки или файлах конфигурации (.wgetrc или .netrc)
3 - Ошибка файлового ввода/вывода (I/O error)
4 - Ошибка сети (например, при обрыве связи)
5 - Ошибка SSL
6 - Ошибка идентификации (неправильное имя пользователя или пароль)
7 - Ошибка протокола
8 - Ошибка сервера (например, нужный файл на сервере не найден, ошибка 404)

За исключением 0 и 1, коды выхода с меньшими номерами имеют приоритет над кодами с большими номерами, когда встречаются многочисленные типы ошибок.

Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2020/02/18/linux-wget-kody-vozvrata-zaversheniya-kody-oshibok-wget/

Linux wget, тайм-аут и повторы. "Виснет" wget при разрыве связи.

Преамбула


Написали тут с вопросом, мол виснет у нас программа, почему никто не знает, кто ее писал уволился давно, поможи. Ну от чего же не помочь. Программа оказалась башевским скриптом, точнее, набором скриптов. Задача небольшая, выгрузить файл с удаленного сервера, переформатировать и положить на другой сервер, где его подхватывает бухгалтерия. Выгрузка делалась банальным wget.

Проблема


Оказалось, скрипт вис, если пропадало соединение с сетью.
Выгрузка производилась простой командой:

wget -O "~/buh01/data/kassa01.dat" "https://example.org/mag01/kassa.dat"

Решение


Оказывается, у wget не проставлен тайм-аут ожидания, а по умолчанию, если его не проставить, wget будет ждать аж 900 секунд (15 минут). Надо, соответственно, его напрямую указать в параметре ключа -T <секунды> (--timeout=<секунды>),
Например, можно поставить вменяемые полминуты (30 с.):

wget --timeout=30 -O "~/buh01/data/kassa01.dat" "https://example.org/mag01/kassa.dat"

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

Заодно можно указать wget'у количество попыток для скачивания файла: -t <число> (--tries=<число>), тем более, что указание параметра -O (имя выходного файла) сбрасывает этот параметр в 1.

wget --timeout=30 --tries=3 -O "~/buh01/data/kassa01.dat" "https://example.org/mag01/kassa.dat"

Полезные ссылки


Шпаргалка по Wget. Копия в PDF

Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2020/02/18/linux-wget-tajm-aut-i-povtory-visnet-wget-pri-razryve-svyazi/

Linux dialog --infobox с "мельницей", скрашивающей процесс ожидания.

Сделал гибрид старого скрипта waiter (копия) с dialog --infobox. В infobox'е отображается псевдографическая "мельница"



https://www.youtube.com/watch?v=o9KempHy5To

Не стал уж совсем дублировать waiter, так что никаких параметров демо-скрипт не принимает, просто отсчитывает 10 секунд, показывая псевдографическую "крутилку".

Исходник на GitHub

Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2020/02/17/linux-dialog-infobox-s-melnitsej-skrashivayushhej-protsess-ozhidaniya/

Linux. Удалить комментарии из файла.

Заметка от склероза. Способ ниже удаляет закомментированные, а заодно и пустые строки из файла, но не трогает комментарии в строках. Хорошо помогает почистить какой-нибудь конфиг, в котором комментариев больше, чем самих параметров, и хрен че найдешь:

grep -o '^[^#]*' file.txt > cleaned.txt

Вместо file.txt подставляем исходный файл, вместо cleaned.txt - выходной.

Нашел здесь Копия в PDF

Там есть и другие варианты решения задачи.

Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2020/02/15/linux-udalit-kommentarii-iz-fajla/

Tags: ,
Замена концов строк MAC (CR, 015 OCT, 0xD HEX) на концы строк Linux (LF, 012 OCT, 0xA HEX)

Преамбула


Понадобилось для работы. Современная MacOS такие концы строк не использует, а некоторое ПО, для совместимости со старыми маками (LC II/LC III) их еще использует. И сами маки в качестве терминалов для наблюдения за датчиками погоды еще юзаются. И живые. Я на таких учился в школе.

Это же аптайам > 20 лет, хуясе. Сии компьютеры младше меня на 5 лет всего. А по характеристикам Intel 486DX 286, ну 386 в лучшем случае, а на них есть оконный интерфейс. Правда, консоли нет и коды ошибок уже не найти (а там скудные сообщения об ошибках - messagebox с кодом).

Решение


cat "file.txt" |tr '\015' '\012' >"file2.txt"

Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2020/02/12/zamena-kontsov-strok-mac-cr-015-oct-0xd-hex-na-kontsy-strok-linux-lf-012-oct-0xa-hex/

Linux. Кодирование/декодирование файлов в/из BASE64

Преамбула


Как однажды сказал мой учитель, "линукс может все, а многое еще и из коробки, надо только знать как". Вот в данном случае именно так и оказалось. Понадобилось мне массово перекодировать файлы в/из BASE64.

BASE64 это такой древний формат данных, использующийся для передачи двоичных данных по сети. В век всеобщего юникода и кучи всякого софта это не так видно пользователю, но когда все только начиналось, с передачей данных была большая жопа. Даже на "железном" уровне некоторые машины поддерживали только семибитную кодировку, а уж о софте, не поддерживающем ничего кроме великого и могучего английского языка и говорить не приходится. Т.е. любой символ кроме букв английского алфавита и цифр мог быть либо выкинут к чертям собачьим, либо невозбранно использован как служебный. Соответственно, любой бинарный файл мог каким либо софтом, например, хитровыебанным почтовым сервером, разорван в клочья при передаче из пункта А в пункт Б.

Вот и придумали умные люди, а давайте все, что не влазит в английский алфавит и цифры, будем по хитрому алгоритму заменять, таки да. На английский алфавит и цифры. Так и получился BASE64. Подобная хрень в криптографии называется "транспортная броня".

Так вот, в Linux из коробки (входит в пакет Coreutils, который есть почти везде) есть утилита, способная кодировать/декодировать BASE64. Называется она, внезапно, base64.

Кодирование


Для опытов возьмем восьмибитного Сиро Исии. Он, когда живой был, много кого брал на опыты.



base64 isia.png >isia.b64

Закодированный Сиро Исии на Pastebin

Декодирование


base64 -d isia.b64 >isia.decoded.png

Тот случай, когда суть получилась короче преамбулы.

Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2020/02/12/linux-kodirovanie-dekodirovanie-fajlov-v-iz-base64/

Tags: ,
Аналог trim() в bash/linux shell

Преамбула


Пишу небольшой скрипт, для которого надо сохранять две выбранные пользователем при предыдущих запусках скрипта опции, а при следующих запусках их восстанавливать.
Решил воспользоваться самым простым методом. Создаем рядом со скриптом 2 файла, и туда сохраняем значения опций:

echo "$OPT1" > ./option1
echo "$OPT2" > ./option2


Некрасиво, но просто.

При запуске скрипта, читаем опции обратно:

OPT1=`cat ./option1`
OPT2=`cat ./option2`


На всякий случай лучше обрезать лишние пробелы или "пустые" символы типа TAB или переводов строки. Во всяком случае, так рекомендуют во всех руководствах по программированию, и обычно, в каждом современном языке, в некотором виде есть функция trim(), которая обрезает начальные и конечные пробелы.

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

Тестовый файл и вывод его в консоль


Возьмем, например, такой тестовый файл: На PasteBin

Если мы просто выведем его на консоль с помощью команды cat "trimtext.txt", то получится следующее:


smallwolfie@wolfschanze:~/myfiles/test/trim# ./testtrim


                   Trim()

smallwolfie@wolfschanze:~/myfiles/test/trim#


т.е. со всеми пробелами и пустыми строками.

Решение


Самая простая реализация trim() в shell/bash пропустить вывод команды через xargs без параметров. xargs, которая требует после себя команды, без указания команды все равно что echo без параметров. А echo без параметров все пустое обрезает.

#!/bin/bash

cat "trimtext.txt"|xargs


Вывод:

./testtrim
Trim()


Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2020/02/08/analog-trim-v-bash-linux-shell/

Tags: ,
Модифицировал заметку про опасность использования eval в bash

Об опасности использования eval в bash-скриптах.

Копия на LJR

За ценное дополнение спасибо [info]wasserstrahl

Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2020/02/08/eval/

Linux dialog, прикручиваем симпатичный progressbar к wget.

Преамбула


Какой бы ваш скрипт не был диалоговым, "само дерево жужжать не может", а в скрипте обычно жужжат утилиты, которые о диалоговых окнах представления не имеют. Так вот прикрутим контролируемый прогрессбар (--gauge) из виджетов dialog к всем известному wget.

Готовый код


#!/bin/bash

FADDR="http://tolik-punkoff.com/static/test.mp3"

wget --progress=dot -O "./test.mp3" "$FADDR" 2>&1 |\
stdbuf -o0 awk '/[.] +[0-9][0-9]?[0-9]?%/ { print substr($0,63,3) }' | \
dialog --gauge "Download file from $FADDR" 10 100



Разбираем, что он делает


1. Если просто запустить wget без параметра --progress=dot (параметр -O "./test.mp3" здесь показывает путь и имя для сохраняемого файла, для теста оно у нас жестко задано), то wget попытается нарисовать свой плохенький progressbar:



Использование параметра --progress=dot приводит вывод на экран в такой вид:



Теперь у нас видны проценты, которые выводятся по штуке на строчку через определенный интервал времени по внутреннему алгоритму wget.

2. wget почему-то выводит сообщения о своей работе не на stdout, а на stderr. Аж морово поветрие какое-то, ибо и некоторые другие утилиты тоже выводят на stderr. Оправданно на stderr выводит сообщения только dialog, тому ще он всю псевдографику выводит на stdout. Отучаем wget писать на stderr вместо stdout:

2>&1

2 - зарезервированный канал для stderr 1 - для stdout. Тут мы просто перенаправляем один канал в другой.

3. Меняем буферизацию. На самом деле, буфер консоли (терминала) выводит на экран сообщение, если в буфере консоли накопилось 1024 байта. Или программа завершилась. Иначе нет. С помощью утилиты stdbuf устанавливаем буфер stdout (-o) в ноль (-o0), тем самым мы добиваемся, чтоб символы сразу поступали на вход awk. stdbuf в качестве второго параметра требует программу, которой она будет посылать измененный буфер. В данном случае awk.

buffering in standard streams
man stdbuf на русском

За разъяснение спасибо другу из Телеграм.

4. Далее вывод wget'а передается awk, которая хитрой регуляркой и оператором substr вырезает из вывода все, кроме значений процентов.



5. dialog --gauge может принимать из stdout числа, и отображать их в виде progressbar'а



Пример на GitHub

Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2020/02/05/linux-dialog-prikruchivaem-simpatichnyj-progressbar-k-wget/

Tags: , ,
Linux. Определить в скрипте, что программа не найдена. И другие зарезервированные коды завершения.

Преамбула


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

Решение


Оказывается в Linux есть стандартные (зарезервированные) коды завершения, а если программа не найдена, то bash автоматически выдает код завершения 127. Таким образом, задача сводится к тому, чтобы на код 127 правильно отреагировать.

Можете проверить на этом скрипте:

#!/bin/bash

$1

EXITCODE=$?

if [ $EXITCODE -eq 127 ]; then
    echo "Command not found!"
else
    echo "Exit code: $EXITCODE"
fi


Проверка


/excode-test ls
excode-test pb01 pb02 test.mp3
Exit code: 0


Команда существует и выполнена успешно.

./excode-test sagfhjsdgfhjgf
./excode-test: line 3: sagfhjsdgfhjgf: command not found
Command not found!


Примечание: Переменная $?, содержащая код завершения, будет переопределена любой следующей командой, потому можно взять за правило, сохранять значение $? в отдельную переменную, если где-то потом в скрипте понадобится проверка кода завершения.

Другие зарезервированные коды завершения


1 - разнообразные ошибки, используется как стандартный код ошибки в скриптах или программах
2 - согласно документации к Bash - неверное использование встроенных команд, иногда программисты его перелпределяют.
126 - вызываемая команда не может быть выполнена, возникает из-за проблем с правами доступа или когда вызван на исполнение неисполняемый файл
127 - "команда не найдена"
128 - неверный аргумент команды exit
128+n - фатальная ошибка по сигналу "n"
130 - завершение по Control-C
255 - код завершения вне допустимого диапазона, но утилита dialog использует этот код, как завершение по ESC.

Источник


Коды завершения, имеющие предопределенный смысл

Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2020/02/04/linux-opredelit-v-skripte-chto-programma-ne-najdena-i-drugie-zarezervirovannye-kody-zaversheniya/

Tags: ,
Linux dialog --menu. Динамическое меню и прочие штуки

Динамическое меню из массива


dialog был бы совсем негибким инструментом, если бы не было возможности формировать элементы меню более-менее "налету", а не только непосредственно в коде скрипта. И такая возможность есть. Виджет --menu (а также --checklist и --radiolist, которые я здесь упущу), принимают на вход массив. Формат массива такой:

MNUARR[0]="Элемент 1"
MNUARR[1]="Описание 1"
MNUARR[2]="Элемент 2"
MNUARR[3]="Описание 2"
...

т.е. линейный массив, где в первый элемент записывается, извиняюсь за тавтологию, элемент, а в следующий - описание, далее все повторяется.

Массив будем брать из файла.

1. Определяем переменную с путем к файлу и массив:

MNUFILE="./dynmenu01.txt"
declare -a MNUARR


2. Заполняем массив:

IDX=0
while read LINE; do
    PT_1=`echo "$LINE"|awk '{print $1}'`
    PT_2=`echo "$LINE"|awk '{print $2}'`
    MNUARR[$IDX]=$PT_1
    let "IDX=IDX+1"
    MNUARR[$IDX]=$PT_2
    let "IDX=IDX+1"
done <"$MNUFILE"


3. Вызываем dialog:

dialog --clear \
    --title "Dynamic menu" \
    --menu "Select option:" \
    20 76 10 \
    "${MNUARR[@]}"




Пример на GitHub
Файл к нему

Меню из файла


Массивом, на самом деле, пользоваться неудобно, и код получается более громоздкий, и несовместимо это может оказаться с другими shell'ами, и возможностей у массива меньше. Есть другой выход - воспользоваться файлом специального формата. Для виджета --menu формат таков:

"Элемент 1"[пробел]"Описание 1"[пробел]\
"Элемент 2"[пробел]"Описание 2"[пробел]\


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

Остается в параметре --file виджета --menu указать путь к файлу.

MNUFILE="./dynmenu-file.txt"

dialog --clear \
    --title "Dynamic menu" \
    --menu "Select option:" \
    20 76 10 \
    --file "$MNUFILE" \




Пример на GitHub
Файл к нему

Дополнительное описание (помощь) к элементу меню


С помошью общего для dialog ключа --item-help можно добавить к элементам подсказку, появляющуюся в выделенной строке внизу экрана. Подсказка ограничена количеством символов в строке, что не влезло - уползает за экран.

Формат файла для такого меню будет:

"Элемент 1"[пробел]"Описание 1"[пробел]"Помощь 1"[пробел]\
"Элемент 2"[пробел]"Описание 2"[пробел]"Помощь 1"[пробел]\


Точно также меню с помощью описывается и непосредственно в коде скрипта.

Вызов dialog:

MNUFILE="./dynmenu-file-help.txt"

dialog --clear \
    --item-help \
    --title "Dynamic menu" \
    --menu "Select option:" \
    20 76 10 \
    --file "$MNUFILE" \


Для динамического меню из массива это не работает (или я не понял как).



Пример на GitHub
Файл к нему

Разделители, или отображение небольших табличных данных в меню


Конечно, виджет --menu, это вам не DataGridView из .NET Framework, и вообще, отдельного виджета для отображения табличных данных у dialog нет, но, если данных немного, то можно воспользоваться общим параметром для виджетов dialog
--column-separator. Раз параметр общий, то кроме --menu, должен срабатывать и для --checklist и --radiolist.
После параметра --column-separator задаем, собственно, сам разделитель (в примере |).

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

MNUFILE="./dynmenu-file-sep.txt"

dialog --clear \
    --item-help \
    --column-separator "|" \
    --title "Dynamic menu" \
    --menu "Select option:" \
    20 76 10 \
    --file "$MNUFILE" \




Пример на GitHub
Файл к нему

Эта опция работает и для динамического меню, созданного с помощью массива:

Пример на GitHub
Файл к нему

Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2020/02/02/linux-dialog-menu-dinamicheskoe-menyu-i-prochie-shtuki/

Tags: , ,
Linux dialog --menu, пункт по умолчанию и сохранение выбранного элемента

Преамбула


dialog - консольная утилита, позволяющая встраивать в ваши скрипты псевдографический интерфейс. Есть и ее графические варианты Kdialog, Xdialog, позволяющие обеспечить ваши скрипты даже полноценным оконным интерфейсом в средах X-сервера.

Как пример можно привести скрипт пакетного переименования файлов (см. на GitHub) работающий в графической среде, или пакетный менеджер Slackware pkgtool.


pkgtool вид спереди


Утилита древняя, как копролиты динозавра, но почему-то при этом на русском довольно мало примеров в сети и нет хорошей документации, и даже официальные примеры кода не полные, да еще и удалены в некоторых пакетах и их приходится искать отдельно. Слава Ктулху, примеры свободные, потому не грех и перезалить.

Примеры на GitHub

Общий синтаксис


Общий синтаксис утилиты dialog таков:

dialog <общие_параметры> <виджет> <параметры_виджета>

Пункт меню по умолчанию


Указание пункта меню по умолчанию возможен не только в виджете --menu, но и в других виджетах, потому прописать его надо в параметрах, указанных до вызова конкретного виджета.

Если будет указан несуществующий пункт меню или пустая строка, к ошибке это не приведет. Будет выбран первый пункт меню.

dialog --clear --title "Default Item Test" \
    --default-item "Item #2" \
    --menu "Select item:" \
    20 51 7 \
    "Item #1"  "Test Item #1" \
    "Item #2" "Test Item #2" \
    "Item #3" "Test Item #3" 2>"/tmp/dlgres.tmp"




Код на GitHub

Сохранение пункта меню и последующий его выбор


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

Но с помощью опции --default-item можно сделать так, чтоб при возврате в одно из меню выбирался последний выбранный пункт.

Сохранение последнего выбранного пункта меню в переменную


1. Заводим переменную для временного файла:

TEMPFILE="/tmp/dlgres.tmp"

2. И переменную для хранения пути к самой утилите dialog:

DIALOG="dialog"

Это не обязательно, но удобно, если понадобится переделать скрипт под Xdialog или Kdialog

3. Заводим переменную для последнего выбранного пункта:

LAST_MENU1=""

4. Само меню будем вызывать из функции menu_in_variable()

Далее внутри функции:

5. Заводим константы для кодов возврата программы dialog:

OK_C=0 #Нажата кнопка OK в диалоговом окне
ESC_C=255 #Нажата клавиша ESC
CANCEL_C=1 #Нажата кнопка Cancel в диалоговом окне


Примечание: На самом деле с отслеживанием клавиши ESC у утилиты menu какой-то конфликт с PuTTY, почему-то утилита завершает работу с кодом 255 не только по нажатию ESC, но и по нажатию клавиш F1..F4 Не в PuTTY это не проявляется.

5. Вызываем dialog:

$DIALOG --clear --title "Save last selected item into variable" \
    --default-item "$LAST_MENU1" \
    --menu "Select:" 20 60 7 \
    "Item #1" "Item 1" \
    "Item #2" "Item 2" \
    "Item #3" "Item 3" 2>"$TEMPFILE"


Примечание: dialog записывает в stderr выбранный элемент меню (в случае виджета --menu), потому перенаправляем вывод на stderr во временный файл, путь к которому указан в переменной $TEMPFILE (2>"$TEMPFILE")

6. Сохраняем код возврата:

RETVAL=$?

7. И далее его анализируем. Если нажата кнопка OK, то читаем файл с выбранным пунктом меню в переменную. Если нажата Cancel или клавиша ESC, то на stderr утилита ничего не выведет и временный файл будет пуст.

case "$RETVAL" in
	$OK_C)
		LAST_MENU1=`cat "$TEMPFILE" `
		#...
		;;
	$ESC_C)
		return;;
	$CANCEL_C)
		return;;
esac


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

Сохранение пункта меню в файл


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

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

STATEFILE="./savestate"

И перед вызовом dialog читаем файл в переменную:

if [ -e "$STATEFILE" ]; then
	LAST_MENU2=`cat "$STATEFILE"`
fi


Далее вызываем dialog, анализируем код возврата, и если что-то выбрано, копируем временный файл в файл для сохранения:

$DIALOG --clear --title "Save last selected item into file" \
	--default-item "$LAST_MENU2" \
    --menu "Select:" 20 60 7 \
    "Item #1" "Item 1" \
    "Item #2" "Item 2" \
    "Item #3" "Item 3" 2>"$TEMPFILE"

RETVAL=$?

case "$RETVAL" in
	$OK_C)
		cp "$TEMPFILE" "$STATEFILE"
		LAST_MENU2=`cat "$STATEFILE"`    
		;;
	$ESC_C)
		return;;
	$CANCEL_C)
		return;;
esac


Пример полностью на GitHub

Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2020/02/02/linux-dialog-menu-punkt-po-umolchaniyu-i-sohranenie-vybrannogo-elementa/

Tags: , ,
Выход из X через консоль (и желательно удаленно)

Долго искал, как выйти из X через консоль, и в мануалах ничего не мог найти. Почему-то это нигде толком не описано. Хотя, я думаю, завершить X на другой машине удаленно, имея под рукой только консоль/удаленный терминал, возникала не у меня одного.

И оказалось, что какого-то единственного универсального способа нет.

Проверить runlevel


Runlevel или уровень запуска — это программная конфигурация системы, которая позволяет запускать только выбранную группу процессов на определенном этапе. Их до 10, но нас интересует уровень 3 - многопользовательский (консольный) режим, и уровень 5 (в Slackware - 4), многопользовательский графический режим, в котором X-server запускается по умолчанию.

Если система находится на уровне 4 (5), то способы как либо пришибить иксы могут не сработать, иксы перезапустятся. С уровня 3 можно запустить X-сервер вручную, для этого надо в консоли ввести (обычно) startx. Если система на уровне 3, то иксы сравнительно легко прибить (см. ниже).

Визуально уровень запуска обычно определить легко. 3 - после загрузки ОС будет консольное приглашение ввести логин и пароль, например:

Welcome to Linux 4.4.14-smp (tty1)

wolfsсhanze login:


На уровне 4 (5) на экране будет предложение ввести логин/пароль, но уже в иксовой форточке.
Правда, некоторые не очень популярные дистрибутивы хитрят. Например, Puppy Slacko запускается на уровне 3, а X-сервер вызывает уже из своих инициализационных скриптов.

Можно проверить runlevel и в консоли/терминале:

runlevel

Вывод:

N 3

или

who -r

Вывод:

run-level 3 2020-01-28 07:12 last=S

Переключить runlevel


Неверное, самый универсальный способ завершить работу X-server на лету и через консоль, это переключить runlevel. Команда должна быть выполнена от root.

- Для Slackware:

init 3

- Для дистрибутивов с systemd:

systemctl isolate runlevel3.target

Вернуться в иксы.

Для Slackware:

init 4

- Для дистрибутивов с systemd:

systemctl isolate graphical.target

Переключить runlevel по умолчанию (при старте системы)


- Для Slackware:

1. Под root запускаем mc и идем в /etc
2. Ищем там файл inittab и открываем его в редакторе.
3. Ищем строчки:

# Default runlevel. (Do not set to 0 or 6)
id:4:initdefault:


Они обычно в начале файла.

4. Меняем 4 на 3 и сохраняем файл. Если надо X при старте - меняем 3 на 4. Если что, обычно в файле есть комментарий-подсказка (на буржуйском).

- Для дистрибутивов с systemd:

Чтоб X был выключен по умолчанию:

systemctl set-default runlevel3.target

Чтоб X по умолчанию был включен:

systemctl set-default multi-user.target

Подробнее почитать о runlevel


Runlevel в Unix/Linux Копия

Другие способы завершить X-сервер через консоль.


Опять же, повторюсь, стопроцентно это сработает только если X-server запущен вручную (или через скрипты), когда система находится в runlevel 3.

- Придушить X-сервер совсем:

killall Xorg

- Более аккуратно придушить иксы (для систем с systemd). Надо отправить команду завершения оконному менеджеру.

В общем виде:

systemctl stop display-manager.service

Вместо display-manager.service подставляем свой оконный менеджер (наверное, не все поддерживают, но у меня systemd нет, так что не тестировал):

systemctl stop gdm

- Способ для xfce:

xfce4-session-logout --logout --display :0.0

Корректно срабатывает только с локальной консоли. Удаленно может не работать.

Еще про способы выйти в "чистую" консоль из иксов


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

Для этого надо нажать Ctrl+Alt+F2...F6 и вам откроется чистый терминал. На Ctrl+Alt+F7 обычно сидят сами иксы, и таким образом, можно к ним вернуться. А первый терминал (Ctrl+Alt+F1) иксы занимают под служебные нужды. В некоторых системах для выхода из иксов срабатывает такой способ:

1. Переключиться в первую консоль (Ctrl+Alt+F1)
2. Нажать Ctrl+C/Ctrl+Break

В некоторых системах для выхода из иксов может сработать комбинация Ctrl+Alt+Backspace

В системах, запускающихся в графическом runlevel по умолчанию, это можно использовать для перезагрузки графического окружения, если X зависли (как soft-restart в Windows 98). Так же можно использовать и команду killall Xorg

Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2020/01/25/vyhod-iz-x-cherez-konsol-i-zhelatelno-udalenno/

Об опасности использования eval в bash-скриптах.

Преамбула


В недавнем примере я допустил, что называется, "детский мат", грубую и далеко неочевидную новичку ошибку, о которой, впрочем, все знают. Но прописные истины неплохо повторять, так что не стоит кидаться на эту заметку с криками "боян!!!111пыщ".
Для кого-то может и боян, а кому-то это может быть неизвестно. Или вот я, зная в теории об ошибке, все равно ее допустил, и даже не сразу понял, что я так грубо наебался, и мой скрипт стал небезопасным от слова "совсем".

Исходная задача


Имелся следующий набор данных в виде форматированного текста (таблицы в текстовом файле):

verb666,Misha Verbitsky,+415314499922,42,11:00-16:00
ktvs421,Vasiliy Kotov,+415314499966,77a,00:00-06:00
dkldn89,Dmitry Kaledin,+415314499949,65b,22:00-00:00
vfurry1,Veniamin Furman,+415314499900,99,12:20-19:25
tpunk56,Tolik Punkoff,+415314499911,59,00:00-11:00


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

# ... цикл по строкам
for TMPSTRING in $(cat "testfile.txt")
do
    eval $(echo "$TMPSTRING"|awk -F "," '{print "LOGIN=" dq $1 dq; 
    print "FULLNAME=" dq $2 dq; print "PHONE=" dq $3 dq; print"ROOM=" dq $4 dq;
    print "WORKTIME=" dq $5 dq}' dq='"')

# ... делаем что-то с данными в переменных
done
# ...


Т.е. тут мы сначала получаем строчку текстового файла, передаем ее awk, awk, в свою очередь, возвращает строки:

...
LOGIN="vfurry1"
FULLNAME="Veniamin Furman"
PHONE="+415314499922"
ROOM="99"
WORKTIME="12:20-19:25"
...


Похоже на команду присваивания значений переменным. Да так оно и есть!
Далее, полученная строка передается команде eval.

Опасность eval


В чем опасность eval? Да в том, что эта команда преобразует любую переданную ей строку в команду или команды bash, и немедленно их выполняет. Любую, абсолютно любую строку.

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

verb666,Misha Verbitsky,+415314499922,42,11:00-16:00
ktvs421,Vasiliy Kotov,+415314499966,77a,00:00-06:00
dkldn89,Dmitry Kaledin,+415314499949,65b,22:00-00:00
vfurry1,Veniamin Furman `rm -rf ./testdir`,+415314499900,99,12:20-19:25
tpunk56,Tolik Punkoff,+415314499911,59,00:00-11:00


Тут, после Veniamin Furman вписана команда удаления директории ./testdir в текущем каталоге, а могло быть вписано и $HOME или даже /.

Строки, взятые в двойные кавычки, интерпретируются bash'ем не только, как строки с чисто тестовыми данными. В двойных кавычках можно и нужно сделать подстановку, если это возможно. А символы `` (обратные кавычки) значат, что нужно выполнить команду внктри них, а потом подставить результат в то место, где указано выражение в обратных кавычках.

Таким образом, команда

FULLNAME="Veniamin Furman `rm -rf ./testdir`"
выполнится так:
1. В переменную записывается строка Veniamin Furman
2. Выполняется команда rm -rf ./testdir
3. Вывод команды дописывается в переменную

Соответственно, каталог ./testdir в процессе будет удален.

Общие рекомендации


Всегда держите в голове, что данные внутри eval$() будут исполнены bash'ем, как код (команды оболочки).

Исправление


1. Заменить двойные кавычки (") на одинарные ('). Строки в одинарных кавычках будут интерпретированы просто как текстовые последовательности, и без всякого выполнения и изменения записаны в переменные, так как есть:

eval $(echo "$TMPSTRING"|awk -F "," '{print "LOGIN=" sq $1 sq;
print "FULLNAME=" sq $2 sq; print "PHONE=" sq $3 sq; print"ROOM=" sq $4 sq;
print "WORKTIME=" sq $5 sq}' sq="'")

Вывод:

vfurry1 Veniamin Furman `rm -rf ./testdir` +415314499900 99 12:20-19:25

2. Но и это еще не конец, злоумышленник может обмануть и одинарные кавычки, обернув свою команду в ...одинарные кавычки:

vfurry1,Veniamin Furman '`rm -rf ./testdir`',+415314499900,99,12:20-19:25

Тогда выполнение будет происходить так. Когда очередь дойдет до FULLNAME awk добросовестно выведет:

FULLNAME='Veniamin Furman '`rm -rf ./testdir`'

eval же это также добросовестно интерпретирует. В $FULLNAME будет записано Veniamin Furman, далее закроется одинарная кавычка, т.е. больше ничего в переменную писаться не будет, а далее выполнится rm -rf ./testdir.

Решение таково - удалить или заменить на что-либо безобидное, одинарные кавычки из входной строки перед передачей ее awk. Можно удалить sed'ом:

sed -e 's~'\''~~g'

Код целиком:

eval $(echo "$TMPSTRING"|sed -e 's~'\''~~g'|awk -F "," '{print "LOGIN=" sq $1 sq;
print "FULLNAME=" sq $2 sq; print "PHONE=" sq $3 sq; print"ROOM=" sq $4 sq;
print "WORKTIME=" sq $5 sq}' sq="'")


Вывод зловредной сткроки будет:

vfurry1 Veniamin Furman `rm -rf ./testdir` +415314499900 99 12:20-19:25

Тестовый пример


Файлы:

maketestdir - скрипт для создания тестовых каталогов.

testfile.txt - Тестовый файл. Ошибку безопасности можно обойти, заменив двойные кавычки одинарными в коде.
testfile2.txt - Замена двойных кавычек одинарными не поможет. Необходимо дополнительно удалять одинарные кавычки во входной строке.

wrongcode - файл без исправлений кода (в коде используются двойные кавычки)
wrongcode2 - только первое исправление (в коде используются одинарные кавычки)
goodcode - окончательно исправленный код.

Вызов скриптов: <скрипт> <тестовый файл>

Например:

wrongcode testfile2.txt

Пример на GitHub

Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2020/01/25/ob-opasnosti-ispolzovaniya-eval-v-bash-skriptah/

Tags: ,
Записать вывод awk в несколько переменных bash

Или как раскидать результат работы awk по нескольким переменным.

Преамбула


Предположим, у нас есть некоторая таблица в виде файла CSV с набором полей, например таких Login,FullName,Phone,Room,WorkTime и разделителем полей , (запятая):

verb666,Misha Verbitsky,+415314499922,42,11:00-16:00
ktvs421,Vasiliy Kotov,+415314499966,77a,00:00-06:00
dkldn89,Dmitry Kaledin,+415314499949,65b,22:00-00:00
vfurry1,Veniamin Furman,+415314499900,99,12:20-19:25
tpunk56,Tolik Punkoff,+415314499911,59,00:00-11:00


Нужно вытащить из нее некоторые данные, и далее как-либо обработать. Вытащить данные можно с помощью awk, используя оператор print, но возникает вопрос, как передать данные обратно в bash.

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

awk и eval


В bash есть встроенная команда eval, преобразующая переданную ей строку в команду или набор команд оболочки, и запускающая ее на выполнение. Этим и воспользуемся.

1. Организуем цикл, в котором будем производить обработку данных:

IFS_=$IFS
IFS=$'\n'
for TMPSTRING in $(cat "demotable.txt")
do
#тут будет код
done
IFS=$IFS_


Перед циклом я подправил переменную $IFS содержащую глобальные разделители, в нее, в частности, "смотрят" операторы циклов, чтобы определить, где начинается следующий элемент. По умолчанию переменная $IFS содержит пробел, табуляцию и перевод строки, но поскольку у нас есть данные с пробелом, то это не подходит, цикл будет работать неверно. Потому сохраняем старое значение во временную переменную, устанавливаем новое значение в перевод строки (\n). После цикла возвращаем значение на место.
В цикле организуем разбор данных:

echo "$TMPSTRING"|awk -F "," '{print "LOGIN=" $1; print "FULLNAME=" $2
print "PHONE=" $3; print "ROOM=" $4; print "WORKTIME=" $5 }'


Если запустить скрипт сейчас, то он выведет следующее:

LOGIN=verb666
FULLNAME=Misha Verbitsky
PHONE=+415314499922
ROOM=42
WORKTIME=11:00-16:00


Т.е. уже похоже на присваивание значений переменным bash, но есть проблема. Если мы сейчас скормим вывод awk eval'у, то получим ошибку, например такую:

./awk2vars01: line 8: Verbitsky: command not found

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

awk print и вывод кавычки


Кавычки для оператора print awk являются служебными символами, в двойные кавычки берутся строковые литералы, т.е. те строки, которые нужно вывести без изменений, как например, "LOGIN=" в коде выше, а в одинарные - вся программа awk. Экранирование (\" или \') в операторе print приведет к ошибке.

Решение - завести внутреннюю переменную awk, содержащую кавычку, и печатать ее в нужном месте:

echo "$TMPSTRING"|sed -e 's~'\''~~g'|awk -F "," '{print "LOGIN=" sq $1 sq; 
    print "FULLNAME=" sq $2 sq; print "PHONE=" sq $3 sq; print"ROOM=" sq $4 sq;
    print "WORKTIME=" sq $5 sq}' sq="'"



Поскольку данные строки далее будут переданы в eval и обработаны как команды оболочки, то необходимо позаботиться о безопасности, и использовать только одинарные кавычки, а также удалять одинарные кавычки из входных строк, при передаче их awk:

Об опасности использования eval в bash-скриптах. Копия

Вывод:

LOGIN='verb666'
FULLNAME='Misha Verbitsky'
PHONE='+415314499922'
ROOM='42'


Теперь можно обернуть все это в eval, чтобы раскидать результат работы awk по переменным.

eval $(echo "$TMPSTRING"|sed -e 's~'\''~~g'|awk -F "," '{print "LOGIN=" sq $1 sq; 
    print "FULLNAME=" sq $2 sq; print "PHONE=" sq $3 sq;
    print"ROOM=" sq $4 sq;
    print "WORKTIME=" sq $5 sq}' sq="'")


В демо-скрипте я просто вывожу данные на консоль, в реальном скрипте, что понятно, можно делать обработку данных в переменных bash.

echo "Login: $LOGIN"
echo "Full name: $FULLNAME"
echo "Phone: $PHONE"
echo "Room: $ROOM"
echo "Work time: $WORKTIME"


Вывод:

Login: verb666
Full name: Misha Verbitsky
Phone: +415314499922
Room: 42
Work time: 11:00-16:00
...


Скрипты полностью можно посмотреть на GitHub

Немного об оптимизации )

Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2020/01/21/zapisat-vyvod-awk-v-neskolko-peremennyh-bash/

Tags: , ,
Получение строки с определенным номером из файла в Linux

С помощью sed


sed -n 5p /path/to/file

Получить 5 строку из текстового файла с путем /path/to/file

С помощью awk


awk 'NR == 5' /path/to/file

На мой взгляд sed'ом несколько проще, потому что не нужны лишние движения для подстановки переменных shell/bash-скрипта:

TEXTFILE="/etc/group"
STRNO=5

TMPSTRING=`sed -n "$STRNO"p "$TEXTFILE"`


Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2020/01/19/poluchenie-stroki-s-opredelennym-nomerom-iz-fajla-v-linux/

Tags: ,
Open-AL library for Slackware (библиотека OpenAL для Slackware)

Исходники: openal-soft-1.17.1.tar.bz2
SlackBuild: OpenAL.tar.gz
Он, кстати, почему-то отрабатывает не до конца, библиотеку собирает, а готовый пакет нет.
Готовый пакет: openal-soft-1.17.1.txz

Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2020/01/16/open-al-library-for-slackware-biblioteka-openal-dlya-slackware/

Tags: ,
libpng-12 legacy for slackware (libpng-12 legacy для Slackware)

Библиотека libpng для Slackware, качать здесь (готовый пакет)

Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2020/01/15/libpng-12-legacy-for-slackware-libpng-12-legacy-dlya-slackware/

Tags: ,
Подключение Riseup VPN в Windows XP



Приходится кое-где сидеть на старой машине с XP (хорошо, не с 2000), а безопасно посидеть в интернете хочется. Так что от склероза, и мало ли кому надо будет. Аналогичным образом можно подключить на XP и VPN от calyx.net

Подготовка


1. Необходимо установить OpenVPN для Windows XP:

Скачать с официального сайта:

- Версия x86 (32-разрядная)
- Версия x64 (64-разрядная)

Копии, на случай, если с официального сайта пропадет:

- Версия x86 (32-разрядная)
- Версия x64 (64-разрядная)

2. Далее, качаем конфиги:

Для Riseup:
- C Mega.nz
- C Google.Drive

Для Calyx:
- C Mega.nz
- C Google.Drive

3. Конфиги необходимо распаковать в каталог для файлов конфигурации OpenVPN (C:\Program Files\OpenVPN\config)

Получение ключей и сертификатов


Получение ключей для VPN сделано обычным BAT-файлом, без проверок fingerprint'а сертификата провайдера, а в wget, которым все и выкачивается, указан ключ --no-check-certificate, так что все это дело не сильно секурно.

1. Скачиваем архив с GitHub
На всякий случай копия на Google.Drive и Mega.nz

2. Распаковываем архив в отдельный каталог, пусть будет C:\GetKeys
3. Запускаем командную строку (Пуск --> Выполнить и вводим cmd)
4. Переходим в каталог:

С:
cd \GetKeys


5. Запускаем получение ключей.
Для Riseup:

getkeys.bat riseup.net

Для Calyx, соответственно:

getkeys.bat calyx.net

После того, как батник отработает, в C:\GetKeys образуется подкаталог data с подкаталогами провайдеров. Из C:\GetKeys\data\riseup.net надо скопировать в C:\Program Files\OpenVPN\config файлы cacert.pem и openvpn.pem для Riseup VPN, а для Calyx из C:\GetKeys\data\calyx.net те же файлы, переименовав их, соответственно как cacert_calyx.pem и openvpn_calyx.pem. Или можете отредактировать конфиг calyx-net.ovpn и задать там любые желательные имена.

Теперь можно запускать OpenVPN GUI, выбирать, щелкнув по иконке в трее, нужный конфиг, и соединяться.

Проверка


До соединения:


Riseup:



Calyx )

Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2020/01/12/podklyuchenie-riseup-vpn-v-windows-xp/

Tags: , , ,
Back Viewing 0 - 20