Проще всего сделать sed'ом.
В том же самом файле (добавляем параметр командной строки -i
):sed -i 's/\r$//' file.txt
В другой файл:cat winfile.txt | sed -i 's/\r$//' >linuxfile.txt
Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2019/08/15/zame
Page Summary
October 2025
|
Замена концов строк Windows/DOS (CR LF \r \n) на Linux (LF \n) в bash
Переопределение вывода на другой терминал в Linux
Пришли сегодня ко мне с одной задачкой, мол есть у нас программка, которая висит в фоне и периодически выводит данные в консоль. Неудобно оператору работать, либо что-то другое делать, либо ничего не делать, лишь в консоль смотреть. Даже отдельный комп думаем программке выделить, чтоб она на нем крутилась-вертелась. И нельзя ли так сделать, чтоб программку на другом терминале запустить, чтоб можно было по Ctrl+Alt+F[номер] переключаться, и за состоянием программки смотреть? Вот запустить нельзя, без особого бубна, а вывод переопределить, всегда пожалуйста. Можно пользуясь стандартным перенаправлением ввода-вывода в Linux, заставить программу или скрипт отправлять сообщения на другой терминал. Пусть программка будет называться tscript . За терминалы в Linux отвечают устройства /dev/tty* , например, /dev/tty2 отвечает за терминал, вызываемый по Ctrl+Alt+F2. Например, чтобы программа переопределяла вывод на /dev/tty2 , запускаем ее таким образом:tscript >/dev/tty2 Можно отправить на другой терминал только вывод сообщений об ошибках: tscript 2>/dev/tty2 Чтобы программа работала в фоне, а на том терминале, с которого мы ее запустили, можно было продолжить работу, добавляем после команды знак & :./tscript >/dev/tty2 & Пишем тестовый скрипт, который, скажем, будет бесконечно выводить на консоль случайное шестнадцатиричное число раз в секунду:
Пишем скрипт, который будет убивать тестовый: #!/bin/bash Пишем запускающий скрипт, в котором вывод тестового скрипта переопределяется на терминал tty2 :#!/bin/bash Запускаем тестовый скрипт на текущем терминале: Выполняем запускающий скрипт: Состояние tty1 Вывод на tty2 Исходники примера На GitHub Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2019/08/09/pere NSIS: Совсем коротко про секции
Секции - это удобный механизм, позволяющий обеспечить пользователю выбор компонентов программы, если такие присутствуют. В каждой секции можно создавать свои ярлыки, распаковывать файлы, и производить любые другие действия, практически независимо от других секций. Естественно, значения переменных, измененные в одной секции, в других тоже будут изменены, потому что в NSIS все переменные глобальные. Для самого простого выбора компонентов в NSIS, необходимо вставить в скрипт, перед, собственно, описанием секции, следующий код: ComponentText "Какой-то текст" , например:ComponentText "Choose which features of ${APPNAMEANDVERSION} you want to install." Естественно, ${APPNAMEANDVERSION} должна быть заранее определена:!define APPNAME "SectionsExample" Окно инсталлятора с выбором компонентов В любом NSIS-скрипте должна быть создана хотя бы одна секция, иначе компилятор будет ругаться, и файл установщика не создаст. В самом простом случае, когда не требуется выбор компонентов, создается единственная секция без названия:
Примечание: После конструкции Section идет имя секции, заключенное в кавычки. Если кавычки пропустить, то имя секции будет некорректным, и неверно отобразится в окне выбора компонентов. Попробуйте вставить следующий код в пример, и посмотрите, как он будет работать. Ссылка на пример в конце заметки.
Для чего? Например, у нас есть программа, у которой, в свою очередь есть основные компоненты, например экзешник и DLL, а также дополнительные, которые можно устанавливать, а можно и не устанавливать. И если уж пользователь хочет поставить наше приложение, то он должен установить хотя бы основные компоненты. Для того, чтобы заблокировать чекбокс, прописываем в начале секции конструкцию: SectionIn RO
Для этого ничего делать не надо, только определить секцию с именем в кавычках и дефольными настройками. Пользователь может деактивировать checkbox (снять галочку) в окне выбора компонентов.
Наверное, самый частый вопрос, задаваемый, что в рунете, что в Интернете вообще, по поводу NSIS. Так вот, ларчик открывается просто. Достаточно после Section поставить специальный флаг /o .Пользователь также сможет активировать checkbox (галочку), если ему нужно будет установить данный компонент.
Такие секции не будут отображены в окне выбора компонентов. Их названия пишутся без кавычек и без пробела, а перед названием ставится знак " - ". Код в таких секциях будет выполнен в любом случае, независимо от желания пользователя:
К ним, наверное, относится одна - Uninstall , ну и еще не совсем секция, а встроенная функция, которую можно переопределить, дописав свой код, т.е. что-то типа обработчика событий в "больших" языках, например в C#О секции Uninstall и рассказывать особо не надо, кроме ремарки, что в секции Uninstall "забываются" все значения глобальных переменных и значение переменной $INSTDIR На GitHub Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2019/07/31/nsis-s Интерактивный скрипт, устанавливающий Syslinux
А так же ISO-образ Acronis True Image и Puppy Slacko. Попросили превратить мою заметку про то, как можно пользоваться Acronis True Image без его акронисовского "восстановления при загрузке", превратить в интерактивный скрипт, который делает все то, что описано в заметке, но сам, задавая пользователю наводящие вопросы. Сделал, чо. Правда, скрипт, наверняка, дичайший быдлокод, но работает без ошибок. Единственное что, предварительно надо создать основной раздел ext2/ext3 на жестком диске, и он должен идти первым. Потом установить винды, сделать линуксовый раздел активным, а потом уже запускать скрипт со всеми потрохами. Скрипт дико большой, и отдельно его описывать мне откровенно влом, впрочем, в виде отдельных заметок, все самое основное я в этом блоге уже обсуждал. Эмуляция восстановления при загрузке Acronis True Image с помощью syslinux/extlinux Копия 1. Создание списков (из файлов в каталоге) Копия 2. Простой интерактив в bash-скриптах (запрос Y/N и запрос строки) Копия 3. Простой интерактив в bash-скриптах (меню, списки) Копия 4. Проверка, установлен ли флаг раздела "активный" Копия 5. Определение файловой системы раздела диска в Linux Копия 6. Поиск загрузчика Windows Копия 7. Получение MBR ID и номера раздела, для передачи управления другому загрузчику Копия 8. Число или строка в переменной BASH Копия На GitHub Поскольку, наверняка набыдлокодил, то исправления и дополнения приветствуются. Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2019/06/22/inte Передача управления другому загрузчику по MBR ID в Syslinux.
Раз уж в прошлой заметке зашла речь про chainloading, т.е. передачу управления другому загрузчику из Syslinux, был разобран стандартный способ указания загрузчика в виде записи hdX Y , и определен минус этого способа, то можно рассказать и про устранение этого минуса.Согласно спецификации, управление другому загрузчику можно передать не только указав номер диска и раздела, но и в следующем формате: mbr:<id> [<partition>] где: <id> - уникальный MBR ID Эта схема, конечно, для предыдущего случая, но разделы (а не диски), в обоих случаях нумеруются одинаково. А вот вместо hd0 (hd1 , hd2 ...) будет mbr:<id> .Вот часть измененного конфига syslinux.cfg , где chainloading используется для загрузки Windows со второго раздела на первом жестком диске, только теперь жесткий диск определяется не по номеру, а по MBR ID:
Сделал весь процесс в отдельной функции get_slid() , куда первым параметром передается имя устройства (с номером раздела или без), например, /dev/sda2 .1. Получим имя устройства без пути: T_BN=`basename $1` 2. Получим номер раздела, удалив из начала имени все латинские буквы: T_VOLNUM=`echo "$T_BN" | sed 's/^[a-z]*//'` 3. Получим имя устройства, с полным путем, но без номера раздела: T_DSKNAM=`echo "$1"|sed 's/[0-9]\+$//'` 4. Проверим, не получилась ли пустая строка (может случиться, если в первый параметр что-то не то положили):
5. Получаем идентификатор MBR, способ указан в руководстве по chain.c32 [1]:T_MBRID=`hexdump -s 440 -n 4 -e '"0x%08x\n"' "$T_DSKNAM"` т.е. hexdump читает из MBR устройства 4 байта идентификатора, и выдает их в виде строки требуемого формата. 6. Формируем строку для конфигурации Syslinux: SL_ID="mbr:$T_MBRID $T_VOLNUM" 7. Пример вызова функции:
На PasteBin На GitHub 1. Comboot/chain.c32 2. Syslinux (Русский) Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2019/06/17/pere Преобразование имени раздела и устройства в формат SYSLINUX
Меня спрашивают, а где на практике можно применить "номер буквы в алфавите", про получение которого в bash-скрипте было недавно написано. Вот пример такого практического применения. Известно, что в Linux дисковые устройства представлены в виде /dev/sda , /dev/sdb , /dev/sdc и т.д., а разделы диска в виде /dev/sda1 , /dev/sda2 ...SYSLINUX, точнее его модуль chain.c32 , который может передавать управление другим загрузчикам, использует другой формат: hdD P где: D - номер устройства (диска) в BIOSP - номер раздела на дискеОтсчет дисков ведется с 0, разделов - с 1 (0 - главная загрузочная запись диска) Например, hd0 2 - загрузка должна производиться со 2 раздела первого диска, hd1 1 - с 1 раздела второго жесткого диска, hd3 0 - необходимо передать управление главной загрузочной записи (MBR) четвертого диска.Вот часть конфига syslinux.cfg , где chainloading используется для загрузки Windows со второго раздела на первом жестком диске:
- Минус, связанный с BIOS. Если вдруг порядок устройств в BIOS поменяется, то загрузчик SYSLINUX "заблудится" и попытается передать управление не туда. - Некоторые линуксы меняют порядок именования жестких дисков, т.е. /dev/hda может и не соответствовать первому загрузочному диску. Тут уже зависит от конкретного дистрибутива.Первый минуса можно избежать, используя вместо номера диска MBR ID, но это уже тема для отдельной заметки. chain.c32 Я организовал это в отдельной функции get_sysl_hd() , чтобы было удобно утащить в другой скрипт, буде понадобится. Первый параметр функции - имя устройства, например, /dev/sda11. Получаем имя устройства без пути к нему. T_DN=`basename $1` 2. Можно проверить, соответствует ли имя устройства формату имени дисков, а то вдруг нам CD-ROM подсунули :) Имя диска начинается с первой буквы s или h на некоторых пожилых дистрибутивах, далее следует буква d , далее - латинская буква a-z , потом могут следовать цифры (номера разделов). Можно сообразить вот такое простенькое регулярное выражение:^[sh]d[a-z][1-9]*$ Далее пропускаем результат работы basename через grep , и проверяем выхлоп в переменной. Если переменная пустая, подсунули что-то не то.
Но на самом деле, эта проверка не очень-то и нужна, можно пропустить этот пункт 3. Получаем третью букву в имени диска с помощью команды expr :expr substr pos len где: substr - операция получения подстрокиpos - позиция символа в строке (отсчет ведется с единицы)len - длина подстрокиT_3LET=`expr substr $T_DN 3 1` 4. Получаем номер буквы в алфавите. Я воспользовался вторым копия из ранее описанных способов. S_CODE=`printf '%d' \'$T_3LET` 5. Получим номер раздела, удалив sed 'ом все латинские буквы с начала имени устройства в переменной $T_DN :
Если переменная окажется пустой, значит нам подсунули устройство, без указания раздела - необходимо сослаться на MBR. Присваиваем T_VOLNUM значение 0 .6. Добавляем полученные данные в переменную SYSL_ID SYSL_ID="$SYSL_ID $T_VOLNUM" 7. Пример вызова функции:
На PasteBin На GitHub 1. Syslinux (Русский) 2. Работа со строками 3. BASH: Получить номер буквы в латинском алфавите, более элегантное решение. Копия Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2019/06/15/preo BASH: Получить номер буквы в латинском алфавите, решение "в лоб".
Вот еще одно решение задачи про номер буквы в латинском алфавите (это подойдет и для русского, нужно просто изменить паттерн). Решение не очень красивое, зато дико простое. На PasteBin На GitHub 1. С помощью операторов for и if Копия2. С помощью printf КопияЭто репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2019/06/08/bash-p BASH: Получить номер буквы в латинском алфавите, более элегантное решение.
В комментариях предложили более элегантное решение этой задачки. 1. printf - команда, выводящая текст (обычно на экран), с учетом заданной форматирующей строки. Подробнее о команде printf можно почитать в источниках, а вообще башевский printf , является аналогом printf из C++, и ее рекомендуют для замены древней команды echo в bash-скриптах.Первым параметром является строка, описывающая формат, в данном случае '%d' означает, что нужно вывести десятичное число.Второй параметр - выводимая строка. Перед вторым параметром добавляется символ ' (одна одинарная кавычка): Интерпретируется как кодовый номер этой буквы в текущей кодировке [1], одинарную кавычку экранируем символом \ .Таким образом, в переменной code окажется код первого символа из первого параметра командной строки скрипта.2. Далее, таким же образом, получаем код первой буквы в алфавите. 3. В итоге, получаем номер буквы в алфавите, посчитав выражение с помощью оператора expr [2]1. Этот код не будет работать на некоторых довольно странных устройствах, где кодовая таблица латинского алфавита представляет собой перемежающиеся заглавные и строчные буквы: AaBbCcDd и т.д. (или aAbBcCdD...) 2. Чтобы отсчет букв шел с единицы, необходимо изменить выражение answer=$( expr $code - $a_code ) на answer=$( expr $code - $a_code + 1 ) 3. С кириллицей этот способ не сработает, используйте предыдущий По вкусу можно добавить проверки, как в предыдущем скрипте. На GitHub На PasteBin 1. Статья про printf 2. Описание оператора expr Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2019/06/04/bash-p BASH: Получить номер буквы в латинском алфавите.
Вопрос был задан студенту-первокурснику преподом на зачете по Linux. Студент на вопрос не ответил и вчера ушел на пересдачу, впрочем, задав вопрос мне. Думаю, формулировка задания понятна. Я, кстати, сначала тоже запарился, и начал выдумывать всякие дикие варианты с получением кода символа, преобразованием кода символа в номер буквы латинского алфавита, потом подумал, что иметь секс с локалью (разбирайся еще, юникод не юникод) не стоит, и родил вот такое простое решение с помощью цикла for и оператора if .Нужную букву будем брать из параметра командной строки скрипта.
Перебираем в цикле все буквы от a до z , нашли нужную - выводим номер, не нашли - увеличиваем счетчик $SNUM .Чтобы отсчет шел с 0 , просто присваиваем начальному значению счетчика 0 :SNUM=0 Чтобы пользователь не ввел ничего лишнего, а только маленькую латинскую букву, можно добавить проверку перед циклом for :
И заменить в цикле и далее $1 на $SFND .На PasteBin На GitHub Есть и более элегантное решение. Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2019/06/04/bash-p Получение относительного пути в Linux
Почему-то много написано, про то, как относительный путь преобразовать в абсолютный, или же получить абсолютный путь к текущему каталогу, а как получить относительный путь из одного каталога в другой, еле нашел. Скажем, есть 2 каталога, известны полные пути: /tmp/test/dir1/subidr1/startpoint и /tmp/test/dir2/subdir2/endpoint , надо получить относительный путь из каталога startpoint в каталог endpoint Проще всего получить относительный путь командой realpath со следующими параметрами:realpath --relative-to="ОТКУДА" "КУДА" где: ОТКУДА - стартовый каталогКУДА - конечный каталогВыполнение команды realpath --relative-to="/tmp/test/dir1/subidr1/st выведет на экран относительный путь: ../../../dir2/subdir2/endpoint Если каталог не существует, будет отображена ошибка: realpath: /tmp/test/dir2/subdir2/endpoint: No such file or directory Утилита realpath входит в пакет coreutils, поэтому есть везде, кроме старых и совсем урезанных дистрибутивов:#!/bin/bash На PasteBin На GitHub qaru.site - там предлагаются и другие способы, разной степени велосипедности, например, использовать Python или получать относительный путь исключительно средствами оболочки (на мой взгляд, неудобно, и можно где-нибудь накосячить). Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2019/06/02/polu Простой интерактив в bash-скриптах, часть 2. Списки (меню).
В bash-скрипте можно организовать простое меню, в виде списка, и предоставить пользователю выбор из нескольких вариантов. Список вариантов можно сформировать вручную, просто перечислив нужные в скрипте. Другой способ - сформировать список динамически, так, как это, например, описано здесь копия. Покажу второй способ. Сначала возьмем из скрипта по ссылке выше функцию create_list() и необходимые переменные:
Организуем это дело в виде отдельной функции ask_list() , куда первым параметром передается список, а вторым - запрос для пользователя.1. Скопируем содержимое первого параметра в переменную $LIST_BUF , со списком придется сделать несколько преобразований: LIST_BUF=$1 2. Список у меня в виде строк, разделенных стандартным переносом \n , так что заодно добавлю пункт Cancel, чтобы пользователь мог отказаться от выбора.LIST_BUF="$LIST_BUF""Cancel" 3. Оператор select работает со списком значений, разделенных пробелами, так что надо символы \n заменить на пробелы:LIST_BUF=`echo -e "$LIST_BUF"|sed 's/\n/ /'` 4. Устанавливаем подсказку ввода для пользователя, присвоив второй параметр функции специальной переменной PS3 .PS3=$2 5. Теперь используем оператор select :
На экран будет выведен список, а пользователю будет предложено ввести номер из списка: smallwolfie@wolfschanze: ~/test/$ ./asklist2 Если внутри конструкции select..done не поставить break , то цикл выбора окажется бесконечным. Значение (строка после номера) будет записано в переменную, указанную после ключевого слова select .Если пользователь введет номер не из списка, или вообще что-то левое, то переменная $LIST_RET окажется пустой. Здесь внутри конструкции select..done добавлена конструкция для проверки этого. Если переменная окажется пустой - пользователю будет предложено повторить ввод:smallwolfie@wolfschanze: ~/test/$ ./asklist-select Функция целиком:
Пример вызова функции:
Результат: smallwolfie@wolfschanze: ~/test/$ ./asklist-select smallwolfie@wolfschanze: ~/test/$ ./asklist-select Скрипт на GitHub Скрипт на PasteBin ( Под катом ) Взаимодействие bash-скриптов с пользователем. Часть 2 Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2019/05/13/pros Простой интерактив в bash-скриптах
Иногда полезно иметь в своих скриптах элемент интерактивного взаимодействия с пользователем, например, запросить с клавиатуры некую строку (путь, пароль, имя пользователя и т.д.), или получить от пользователя подтверждение действия ( Вы уверены? [Y/n] ). Далее покажу простейшие случаи.Все, кто хоть раз пользовался для создания нового пользователя скриптом adduser , наблюдали на экране следующую картину:Login name for new user []: wolfkid Понятно, что где-то можно (и нужно) ввести свои данные, а где-то согласиться с предлагаемыми скриптом по умолчанию (или не согласиться, ввести свое). Вопрос, как такое сделать в своем скрипте? В данном случае можно воспользоваться командой read .Общий синтаксис: read [ПАРАМЕТРЫ] [ПЕРЕМЕННАЯ] Если имя переменной не будет указано, то, что было введено с клавиатуры попадет в специальную переменную $REPLY .Обратите внимание: в команду read имя переменной подставляется без символа $ . Т.е. если вы хотите, чтоб введенная строка оказалась в переменной VAR1 , то синтаксис такой:read VAR1 Напишем функцию, которая будет принимать два параметра - строку с пояснением, что мы хотим, чтоб пользователь ввел, и строку, которая будет представлять значение по умолчанию. В случае, если пользователь что-то ввел, то функция запишет в переменную $STR_RESULT новое значение. Если же пользователь просто нажмет Enter, то в $STR_RESULT будет записано значение, переданное во втором параметре.
Небольшое пояснение по используемым параметрам read :-r - отключает режим интерпретации эскейп-последовательностей, т.е. \n , \r , \t и т.д. не будут записаны в переменную, как символы возврата каретки, перевода строки или табуляции, а будут восприниматься, как символьные последовательности - слэш и буква.-p [СООБЩЕНИЕ] - СООБЩЕНИЕ , это строка, которая будет выведена пользователю перед тем, как он сможет ввести данные.Пример вызова функции: ask_string "Select path" "/home/smallwolfie/test/testdir" Вывод: Пользователь нажал Enter, оставив значение по умолчанию: smallwolfie@wolfschanze:~/test/input01$ ./askstring Пользователь ввел другое значение: smallwolfie@wolfschanze:~/test/input01$ ./askstring Готовый скрипт на GitHub Готовый скрипт на PasteBin Обычный запрос Вы уверены [Y/N] . Для удобства использования (т.е. копипаста в другие скрипты) тоже можно реализовать в виде отдельной функции, которой передается один параметр - строка с вопросом для пользователя:
Пояснения: 1. Командой echo -n "$1 [Y/N]: " выводим пользователю сообщение с пояснением, что надо нажать (Y или N ). Параметр -n в команде echo запрещает ей переводить курсор на новую строку. Опцией -p команды read не пользуемся для красоты, иначе сообщение будет выскакивать при каждом нажатии клавиши, и заполнять экран.2. Организуем бесконечный цикл: while [ 1 -eq 1 ];do Единица всегда равна единице, поэтому цикл не завершится, если не будет какого-то прерывания внутри цикла. 3. В начале цикла вставляем команду read со следующими параметрами:-s - не отображать вводимые пользователем символы на экране-n1 - читать 1 символ, и завершаться, не дожидаясь нажатия клавиши Enter.4. Далее в операторе case проверяем, что было нажато: если Y или y , то пользователь ответил "да", если N или n - "нет". Ну не заставлять же пользователя регистр символов отдельно проверять... Возвращаем соответствующий код возврата 0 для "да", 1 для "нет"Пример вызова функции:
Вывод: Пользователь не нажал ничего, или нажал что-нибудь кроме YyNn :smallwolfie@wolfschanze:~/test/input02$ ./askyn Пользователь ответил "Нет": smallwolfie@wolfschanze:~/test/input02$ ./askyn Пользователь ответил "Да": smallwolfie@wolfschanze:~/test/input02$ ./askyn Скрипт на GitHub Скрипт на PasteBin Внутренние команды bash Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2019/05/11/pros Linux. Получение списка файлов по маске с игнорированием регистра символов имени файла.
Всем известна команда ls , выводящая список файлов на консоль. Если требуется вывести только файлы с расширением .iso , то в команду подставляется маска файла: ls *.iso И все бы хорошо, но команда ls , как и другие команды Linux, любит строгое совпадение регистра имен файлов, т.е. если в каталоге есть файлы с расширением .ISO , .Iso и .iso , то ls *.iso выдаст только те, которые с расширением именно что .iso , и проигнорирует остальные. А вот Windows регистр имен файлов глубоко пофиг, хотя, современные версии Windows и сохраняют регистр в имени файлов. Но для аналогичной линуксовой команде ls команды Windows dir , что .ISO , что .Iso , что .iso - равнозначны, и все командой dir *.iso будут выведены.Можно воспользоваться мощной командой find , которая умеет игнорировать регистр имен файлов (на самом деле, она кучу всего умеет, см. в источниках):find <path> -maxdepth 1 -iname <mask> где: <path> - путь к каталогу, в котором производится поиск.-maxdepth 1 - глубина поиска 1 - только в текущем каталоге, без параметра -maxdepth - во всех подкаталогах и ниже.-iname - игнорировать регистр имени файла.<mask> - маска файлаЧтобы обрезать полный путь (а find выдает полный путь к файлу(-ам)) до имени, можно воспользоваться командой basename <path> где <path> - полный путь к файлуОбъединить работу двух команд можно с помощью цикла for Создадим отдельную функцию create_list() , принимающую два параметра - путь к каталогу и маску файла, и выдающую список файлов в переменную $FOUNDLST :
Ясно, что в тестовой директории archives должны лежать архивы *.tar.gz , а в isos - образы *.iso /home/smallwolfie/test/archives *.zip not found На GitHub На PasteBin 1. Команда find в Linux Копия 2. basename 3. Цикл for в bash Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2019/05/07/linu Интересный способ определить, является ли раздел активным (стоит ли флаг boot)
В Linux, с помощью 1. На GitHub 2. На PasteBin 1. The MBR (master boot record) and the Partition Tables. Там как раз подробное описание, как оно выковыривается. 2. Нашел здесь Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2019/04/21/inte Эмуляция восстановления при загрузке Acronis True Image с помощью syslinux/extlinux
Принесли мне тут в починку компьютер с наглухо залитыми эпоксидкой USB портами (безопасность же) и поставили задачу переустановить винды, в связи с заменой сгоревшего HDD на новый. По счастью сетевой порт был, так что единственным доступным способом доставить туда винды, был PXE. Но, в данном случае, речь пойдет не о PXE. Зная клиента, который, несмотря на солидность, периодически "придет, и молча уронит все", я подумал, что так дело не пойдет. Надо предусмотреть возможность восстановить если что, ОС прямо с компьютера. Чтоб клиент не бегал вокруг меня, если уронит винду из-за кривого ПО/рук. Всем хорош образ загрузочного диска Acronis True Image, и копию ОС сделать может, и восстановить может, и Зону Безопасности (скрытый раздел для хранения бэкапов) создать может. Не может лишь одного - установить свой загрузчик, чтобы можно было сделать "Восстановление при загрузке". В десктопной платной версии такая функция есть, а в Recovery CD буржуи ее вырезали. Но мы не дворяне, справимся. Внимание! Все нижеследующее работает для компьютеров с BIOS (или в Legacy-режиме) с MBR-дисками. - Загрузчик syslinux . Можно взять здесь. Я пользовался версией 4.02, которая мне уже была знакома по настройке PXE-сервера. Из архива нам понадобятся только некоторые файлы, но я уже собрал готовый пакет, ссылка на который будет в конце заметки. Вместо syslinux можно использовать какой-нибудь другой загрузчик, который умеет грузить ISO-образы (например grub2 или grub4dos ), но далее все будет про syslinux .Примечание: Вообще syslinux , это набор загрузчиков на разные случаи жизни. Он включает в себя pxelinux (для загрузки из сети), isolinux (для создания загрузочных ISO) и extlinux , для установки загрузчика на жесткий диск. Но, с 4 версии постановили extlinux и syslinux считать одним и тем же [1], так чтоб никого не путать, далее буду называть все syslinux 'ом- Какой-нибудь маленький live-дистрибьютив Linux. Я использовал уже довольно пожилой Puppy Slacko 5.5 Rus, немного модифицированный когда-то давно под работу с tcplay - Собственно сам образ Acronis True Image Recovery CD. Использовал старый, от Acronis True Image 2011, потому что он довольно небольшой (122 Мб против 522 от Acronis True Image 2015, например). Поскольку это софтина проприетарная, пользуйтесь гуглем и торрентами. Я все делал на чистом диске, так что мне было просто. В начале диска создаем основной раздел EXT2 или EXT3, в котором будет установлен загрузчик, лежать образ Acronis True Image, а у меня еще и дистрибьютив Puppy Slacko, чтоб чуть что можно было загрузиться в обход основной ОС. Делаем с помощью любимого менеджера дисков (я пользовался Acronis Disk Director). Структура разделов должна выглядеть как-то так: Желательно сделать раздел для нашего будущего загрузчика в начале диска, чтоб потом не было эксцессов. Когда экспериментировал с этим делом первый раз, Acronis, при создании Зоны безопасности, нагло передвинул раздел, и все пошло прахом. Syslinux, на самом деле, можно ставить и в логические разделы, только это сопряжено с большими телодвижениями (см. в источниках в конце заметки). Установим Windows на свободное место. Установщик Windows 7 и выше сам создаст необходимые разделы под свой загрузчик ( bootmgr и настройки) и основной раздел с ОС. После установки Windows структура диска должна выглядеть так:Сборка пакета для установки загрузчика Просьба линуксоидам камнями не кидаться, "пакет", в данном случае, не совсем то, что подразумевается под пакетом в терминах Linux-систем. В данном случае, это набор файлов, который необходим для установки syslinux на целевой машине. Я делал это на "большом" Линуксе, но можно делать это и на том же самом Puppy (и даже в Windows, хотя на практике я не проверял). Ленивые могут пропустить этот шаг, готовый пакет будет в конце заметки.1. Создаем в удобном месте подкаталог, например slinstall , там будет готовый набор файлов для целевой машины.2. В другой подкаталог распаковываем архив с syslinux (например, syslinux-4.02.tar.gz ), в нашем примере подкаталог будет называться sysl-distr 3. Копируем в каталог slinstall файл extlinux из каталога sysl-distr/extlinux - это установщик загрузчика.4. Создаем в каталоге slinstall подкаталог mbr и копируем туда файлы sysl-distr/mbr/mbr.bin и distr/mbr/altmbr.bin 5. Создаем в каталоге slinstall подкаталог modules и копируем туда модули загрузчика.Syslinux, на самом деле, не просто загрузчик, а, можно сказать, целая маленькая операционная система. Функции загрузчика расширяются модулями - файлами специального формата, которые загрузчик может выполнять, примерно как ОС исполняемые файлы. Файлы эти имеют расширение c32 (*.c32 ). Минимальный набор модулей для нашей задачи - модуль отображения меню menu.c32 и модуль chain.c32 - он передает загрузку другим (не-Linux) операционным системам, загрузчикам, или просто в нужный раздел диска. Но можно скопировать и другие модули, если захочется расширить функционал начальной загрузки. Необходимо найти нужные файлы (через поиск mc в Linux или любым удобным способом) в каталоге sysl-distr и скопировать их в slinstall/modules В Линукс это можно сделать из командной строки так (находясь в каталоге sysl-distr ):find ./ -name "*.c32"|xargs -I {} cp '{}' /home/user/slinstall/modules где /home/user/slinstall/modules - полный путь к подкаталогу slinstall/modules 6. В slinstall/modules необходимо также скопировать специальный модуль memdisk , предназначенный для загрузки ISO-образов. Обычно расположен по пути memdisk/memdisk в каталоге с распакованным syslinux (тут sysl-distr ).7. Пакет готов, теперь можно запаковать его в архив, и приступать к установке загрузчика. В Linux можно выполнить (выйдя из каталога slinstall на уровень выше)tar -czvf syslinux-install.tar.gz ./slinstall Предположим, у нас есть загрузочная флешка с Puppy Linux (или другим Linux на ваш вкус), копируем на нее образ Acronis True Image, выше созданный пакет с загрузчиком, и архив с дистрибутивом самого Puppy (см. ниже, в разделе "Скачать"). В графическом интерфейсе все можно делать мышью, я приведу ниже консольные команды. В данном примере флешка - sdb1 , а созданный ранее раздел - sda1 Внимание! Не ошибитесь в том, как именованы разделов на конкретной машине! 1. Создаем точки монтирования (пропустить шаг, если запущен графический интерфейс Puppy. Просто щелкнуть мышью по нужной иконке диска на desktop'е) mkdir /mnt/sda1 2. Монтируем диски (пропускается из графического интерфейса): mount -t ext3 /dev/sda1 /mnt/sda1 Может быть нужным заменить ext3 на ext2 и/или vfat на ntfs в зависимости от используемых файловых систем.3. Создаем директорию для образа Acronis True Image Recovery CD на разделе sda1 и копируем образ.mkdir /mnt/sda1/acronis 4. Копируем и распаковываем дистрибутив Puppy (если он нужен) cp /mnt/sdb1/puppy-slacko-rus-5.5-hexmod.ta 5. Копируем и распаковываем пакет установки syslinux :cp /mnt/sdb1/ syslinux-install.tar.gz /mnt/sda1/ syslinux производится не на устройство, а на заранее смонтированный раздел. Загрузчик нельзя устанавливать в корень диска, необходимо создать для него каталог, например /boot/syslinux . Не перепутайте разделы диска, куда устанавливаете загрузчик! Раздел с загрузчиком должен иметь файловую систему FAT, ext2, ext3, ext4 или Btrfs1. В любимом менеджере дисков делаем раздел EXT2/EXT3 активным. 2. Загружаемся, если еще не, в live-дистрибьютив Linux. 3. Создаем точку монтирования и монтируем раздел (если еще не сделано) mkdir /mnt/sda1 4. Создаем каталог для загрузчика: mkdir -p /mnt/sda1/boot/syslinux ключ -p указывает команде mkdir , что нужно создавать путь со всеми подкаталогами.5. Создаем каталог для модулей и копируем их: mkdir -p /mnt/sda1/boot/syslinux/modules 6. Переходим в каталог slinstall и устанавливаем загрузчик:cd /mnt/sda1/slinstall Если все сделано верно, последняя команда выдаст сообщение: /mnt/sda1/boot/syslinux is device /dev/sda1 В каталоге /mnt/sda1/boot/syslinux должен находиться файл ldlinux.sys , кстати, неудаляемый. В [1] написано, как его, если что, удалить.Syslinux, внезапно, сам не умеет прописываться в MBR диска, да и в загрузочный сектор раздела. Так что если перезагрузиться сейчас, то получим при загрузке сообщение Boot error и глухое зависание. MBR, к сожалению, придется править вручную, с помощью команды dd .Внимание! Команду dd не зря называют Disk Destroyer, будьте с ней очень осторожны! При ошибке легко можно похерить не только MBR, но и таблицу разделов, и данные на диске!MBR находится в первых 440 байтах на диске. 1. Переходим в каталог slinstall :cd /mnt/sda1/slinstall (естественно, точка монтирования должна быть создана, а раздел примонтирован). 1. Создаем копию текущей MBR: dd if=/dev/sda of=old.mbr bs=440 count=1 В текущем каталоге должен появиться файл old.mbr размером 440 байт. Можно, и даже желательно, указать и какой-нибудь другой путь к файлу old.mbr , сохранив его, например, на флешке:dd if=/dev/sda of=/mnt/sdb1/old.mbr bs=440 count=1 2. Устанавливаем MBR syslinux :dd bs=440 count=1 conv=notrunc if=mbr/mbr.bin of=/dev/sda Примечания: Краткое пояснение по команде dd :bs=<число> - сколько байт необходимо прочитать.count=<число> - число уазывает на то, сколько раз будет прочитано количество байт, указанное в параметре bs= if=<путь к устройству или файлу> - откуда будут прочитаны данныеof=<путь к устройству или файлу> - куда будут записаны данныеОсталось сделать загрузочное меню. Вот пример загрузочного меню, главное, правильно установить раздел с загрузчиком винды - в syslinux отсчет разделов ведется с единицы (0 - MBR жесткого диска), отсчет дисков с ноля, и надо помнить, что единица таймера загрузки syslinux равна 0.1 секунде.
На PasteBin Осталось загрузиться с жесткого диска, создать зону безопасности Acronis и сделать бэкап первых трех разделов в нее Вот финальная структура диска. 1.Syslinux (Русский) 2. Comboot/chain.c32 3. Syslinux wiki puppy-slacko-rus-5.5-hexmod.tar.gz syslinux-install.tar.gz syslinux-mini.tar.gz Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2019/04/19/emul Включение цифровой клавиатуры (NumLock) при загрузке Slackware (и/или X-Server)
Slackware, почему-то загружается по умолчанию с отключенной цифровой клавиатурой, еще и благополучно плюет на опцию Boot Up Numlock в BIOS, благо все это, как оказалось, легко поправить. Раньше было не так актуально, но завелся на работе ноут с полноценной клавой с цифровым блоком. Так что заметка опять же от склероза. Надо помнить, что у нас как минимум 6 терминалов (которые переключаются по CTRL+ALT+F1 - F6), можно активировать цифровую клавиатуру для всех шести, таким вот простым скриптом:
Сохраняем, например в /etc , под именем, скажем, numlockon , и дописываем в /etc/rc.d/rc.local Код на PasteBin Можно вообще не делать отдельный файл, а прямо в rc.local записать все в одну строку:for TTYNUM in 1 2 3 4 5 6; do; /usr/bin/setleds -D +num < "/dev/tty$TTYNUM"; done Кому почему-то первая версия не подходит, можно попробовать версию с ArchLinux вики, там активируется NumLock на консолях от tty0 до tty9 . Код на PasteBin И даже такой вот говнокод, который оставлю тут ради эгеге, не знаю зачем оно может понадобиться. Скачиваем и собираем утилиту numlockx , она есть в репозиториях sbopkg , например.Потом останется прописать ее в автозагрузку для конкретного пользователя. Тут расскажу про XFCE, остальные будут в источниках. 1. Заходим в Applications --> Settings --> Session and Startup 2. Переходим на вкладку Application Autostart, нажимаем кнопку Add. 3. Заполняем название, описание, вписываем в соответствующее поле саму команду numlockx :4. Готово, закрываем все приложения и перезагружаем иксы: 1. man setleds 2. Activating Numlock on Bootup (Русский) Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2019/04/14/vkly Добавление русской раскладки в X-Server на Slackware
1. Копируем файл 1. Slackware.ru 2. Всякие дополнительные подробности на wiki.archlinux.org Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2019/04/13/doba Скрипт для поиска загрузчика Windows из Linux-окружения.
Найти загрузчик Windows на разделе жесткого диска, дело не очень сложное: 1. Надо проверить файловую систему раздела, она должна быть FAT32 или NTFS 2. Проверить наличие файла ntldr (Windows XP и ранее) или bootmgr (Windows Vista и позднее) в корне раздела. Windows XP и старше, при установке по умолчанию, записывают файл ntldr в корень системного раздела, а более новые - создают отдельный загрузочный раздел, в корне которого лежит bootmgr . Для чего? Например, для создания своего скрипта автоматической настройки загрузчика Grub или Syslinux Я недавно писал о том, как узнать файловую систему раздела (диска) в Linux Копия. В данном случае действовать будем примерно также. Обработать вывод команды blkid (вывод данных о блочных устройствах) можно в цикле for :echo "Find Windows loaders..." Перед циклом необходимо установить значение переменной IFS , как \n (перенос строки)IFS - переменная, задающая разделители полей при работе со строками в shell, по умолчанию разделители это табуляция, перенос строки и пробел, если не установить ее значение, как "только перенос строки", то строка с описанием каждого раздела (например, /dev/sda1: UUID="68DF-FF87" TYPE="vfat" PARTUUID="00003214-01" ) распадется на части, что поломает алгоритм.В цикле for :1. Вытаскиваем в переменную VOL нужные данные - путь к устройству и файловую систему:VOL=`echo "$DEVDATA" |sed -n 's/\(.*:\).* TYPE=\"\([^\"]*\)\".*/\1\2/p'` Для вышеуказанного /dev/sda1 получится строка /dev/sda1:vfat 2. Получаем путь к устройству и тип файловой системы отдельно в переменные, соответственно, VOLNAME и VOLFS .VOLNAME=`echo "$VOL"|awk -F ":" '{print $1}'` Параметр -F ":" устанавливает двоеточие в качестве разделителя полей awk .3. Далее, проверяем, не пуста ли строка в переменной VOLFS , и проверяем ее значение. Если VOLFS равна ntfs или vfat , то запускаем функцию find_loader() , проверяющую наличие загрузчика в корне соответствующего раздела. Если файловая система раздела другая - выводится сообщение, что это не Windows-раздел.
Можно было бы еще исключать разделы FAT16, но решил не загромождать скрипт лишней проверкой. В функцию find_loader() передаются два параметра: путь к устройству (разделу) и его файловая система.1. Заведем переменную-флаг, указывающую, был ли раздел временно смонтирован TMPMOUNT=0 2. Получаем выхлоп команды mount . grep 'ом фильтруем вывод по соответствующему разделу, с помощью awk вытаскиваем точку монтирования.MOUNTPOINT=`mount|grep -w "$1"|awk '{print $3}'` 3. Если переменная MOUNTPOINT пустая, раздел не смонтирован. Создаем временную точку монтирования, пытаемся смонитровать раздел, если получилось - устанавливаем TMPMOUNT=1 , в переменную MOUNTPOINT записываем временную точку монтирования и приступаем к поиску загрузчика, если не получилось - выходим из функции:
Примечание: ключ -p команды mkdir позволяет создать путь вместе со всеми подкаталогами, а если путь уже создан, то команда mkdir не выдаст ошибки, что путь уже существует.Надо обратить внимание на то, что Windows нечувствительна к регистру имен файлов, так что загрузчик может быть и bootmgr и BOOTMGR , и даже BoOtMgR (аналогично и ntldr ). Поэтому придется воспользоваться командой find .find <path> -maxdepth 1 -iname <filename> где: <path> - путь к каталогу, с которого начинать поиск-maxdepth - глубина поиска в подкаталогах (начиная с указанного в <path> , 1 - только каталог <path> без подкаталогов).-iname - игнорировать регистр имени файла<filename> - имя файла (или маска), который будем искать.В данном случае надо обязательно установить -maxdepth 1 , иначе будут большие тормоза, а при отмонтировании возможны глюки.4. Ищем загрузчик Vista и выше и сохраняем выхлоп в переменную FOUND :FOUND=`find "$MOUNTPOINT" -maxdepth 1 -iname "bootmgr"` 5. Если нашли (переменная FOUND не пустая), выводим соответствующее сообщение, если нет - ищем загрузчик Windows XP, и выводим сообщение в зависимости от того, нашли или нет:
6. Проверяем флаг TMPMOUNT , если он был установлен в 1 , отмонтируем временно смонтированный раздел:
Запуск на тестовой машине с разделами FAT32/NTFS, но без установленной Windows: Запуск на машине с установленной Windows 7: Запуск на машине с установленной Windows XP На GitHub На PasteBin 1. Определение файловой системы раздела диска в Linux Копия 2. Команда find в Linux Копия Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2019/03/27/skri Определение файловой системы раздела диска в Linux.
Понадобилось определять файловую систему еще не смонтированного раздела в Linux, я написал скрипт, который мне самому казался громоздким и неудобным, так и оказалось. Но добрый аноним подсказал, в какую сторону копать, и действительно, нашлось хорошее универсальное решение. Для экспериментов создал диск с разделами различных файловых систем: lsblk Показывает блочные устройства (диски, разделы, контейнеры, прикрученные к loop-устройствам, разделы, добавленные kpartx , исключая RAM-диски) по умолчанию в виде симпатичного дерева. Ключ -f заставляет утилиту вывести информацию о файловой системе на конкретном устройстве.lsblk -f Почти то, что нужно, но, к сожалению, есть эта утилита не везде, так что мне она не подошла. blkid При запуске без параметров выводит кучу информации о блочных устройствах (опять же диски, разделы, контейнеры, прикрученные к loop-устройствам, разделы, добавленные kpartx ) в виде строк, по одной на устройство, содержащих пары КЛЮЧ="ЗНАЧЕНИЕ" :Можно обратить внимание на ключ -o - он меняет формат вывода на экран, например, blkid -o list выводит информацию в виде таблицы.Но, к сожалению, менять формат вывода умеют не все версии этой утилиты. Например, "версия", "встроенная" в BusyBox не умеет. Да! Она есть даже в BusyBox! А значит, это, наверное, самое универсальное решение! А с форматированием вывода как-нибудь разберемся. Запуск команды, как blkid <устройство> , например, blkid /dev/sda1 , позволяет вывести информацию о конкретном устройстве.- И у раздела FAT16, и у раздела FAT32 параметр TYPE будет равен vfat , чтобы их отличить друг от друга, надо смотреть в параметр SEC_TYPE , у раздела FAT32 его не будет вообще, а у раздела FAT16 SEC_TYPE="dos" - Если вытащить значение поля TYPE в скрипте, его автоматически можно подставить в команду mount , во всяком случае для FAT16/32, NTFS, EXT2(3, 4) и BTRFSС этой командой скрипт получился крохотным, даже с добавлением проверки кода возврата, задано определенное устройство, или надо вывести все, и проверки, есть ли у определенного устройства поле TYPE . Самое страшное в скрипте - несколько монструозное регулярное выражение для sed , чтобы вытащить имя устройства и его файловую систему.Скрипт целиком:
Можете сравнить с тем монстром, который я набыдлокодил изначально. Оставлю, чтоб иногда самому ужасаться. :) Скрипт (новый) на GitHub Скрипт (новый) на PasteBin Результат работы в нормальном окружении: И в урезанном, с BusyBox'овой "версией" blkid Это репост с сайта http://tolik-punkoff.com Оригинал: http://tolik-punkoff.com/2019/03/26/opre Определение файловой системы раздела диска в Linux (Неудачный и кривой вариант).
Кривой вариант оставлен для архива в основном блоге, а отсюда удален, ибо пусть в одном месте лежит. Вот нормальный вариант. Копия на LJR |