Xargs в действии
Прошлые 2 поста дали нам достаточно информации про утилиту xargs, рассмотрим-ка несколько практических примеров.
Удаление файлов [1]
Одна из самых частых ситуаций использования xargs — удаление группы файлов, найденных при помощи find:
Как можете заметить, тут мы обработали кейс, когда в именах содеражатся пробелы: мы через -print0 указали "\0" разделитель для строк, сформированных командой find и определили "\0" разделитель, по которому xargs будет формировать аргументы.
Удаление файлов [2]
Также можно удалить все файлы, кроме тех, которые подходят под определенный шаблон:
Тут мы рекурсивно удаляем все файлы, кроме ".sh" скриптов.
Переименование файлов
С помощью xargs можно осуществлять массовое переименование файлов.
Представим себе, что у нас есть группа файлов с расширением ".txt", и нам нужно произвести замену на ".sql".
Выполнить задачу можно при помощи xargs и потокового текстового редактора sed:
Можно еще одним интересным способом поменять расширение файлам, используя cut:
Изменение прав
С помощью xargs можно ускорить процесс смены прав на файлы и каталоги для пользователя/группы:
Удаление старых файлов
Вот так, например, можно удалить временные файлы, созданные более 7 дней назад:
Архивация файлов
Иногда может потребоваться вычленить группу файлов по "первичному признаку" и запихнуть все в архив. Следующий пример работает с ".png" файлами:
Форматирование вывода
Если необходимо для дальнейшего оперирования данными отформатировать вывод в строку, можно использовать xargs. Например, выведем список всех пользователей системы:
Команда sort выведет все в столбик, xargs, без параметров, передаст весь вывод команде echo, которая отобразит данные с пробелом, в качестве разделителя:
LinuxCamp
Прошлые 2 поста дали нам достаточно информации про утилиту xargs, рассмотрим-ка несколько практических примеров.
Удаление файлов [1]
Одна из самых частых ситуаций использования xargs — удаление группы файлов, найденных при помощи find:
$ find . -type f -name "*.sh" -print0 | xargs -0 rm -rf
Как можете заметить, тут мы обработали кейс, когда в именах содеражатся пробелы: мы через -print0 указали "\0" разделитель для строк, сформированных командой find и определили "\0" разделитель, по которому xargs будет формировать аргументы.
Удаление файлов [2]
Также можно удалить все файлы, кроме тех, которые подходят под определенный шаблон:
$ find . -type f -not -name '*.sh' -print0 | xargs -0 rm -rf
Тут мы рекурсивно удаляем все файлы, кроме ".sh" скриптов.
Переименование файлов
С помощью xargs можно осуществлять массовое переименование файлов.
Представим себе, что у нас есть группа файлов с расширением ".txt", и нам нужно произвести замену на ".sql".
Выполнить задачу можно при помощи xargs и потокового текстового редактора sed:
$ ls | sed -e "p;s/.txt$/.sql/" | xargs -L2 mv
Можно еще одним интересным способом поменять расширение файлам, используя cut:
ls | cut -d. -f1 | xargs -I{} mv {}.txt {}.sh
Изменение прав
С помощью xargs можно ускорить процесс смены прав на файлы и каталоги для пользователя/группы:
$ sudo bash -c "find ./ -group root -print | xargs chgrp xoadmin"
Удаление старых файлов
Вот так, например, можно удалить временные файлы, созданные более 7 дней назад:
$ find /tmp -type f -name '*' -mtime +7 -print0 | xargs -0 rm -f
Архивация файлов
Иногда может потребоваться вычленить группу файлов по "первичному признаку" и запихнуть все в архив. Следующий пример работает с ".png" файлами:
$ find ./ -name "*.png" -type f -print0 | xargs -0 tar -cvzf images.tar.gz
Форматирование вывода
Если необходимо для дальнейшего оперирования данными отформатировать вывод в строку, можно использовать xargs. Например, выведем список всех пользователей системы:
$ cut -d: -f1 < /etc/passwd | sort | xargs
Команда sort выведет все в столбик, xargs, без параметров, передаст весь вывод команде echo, которая отобразит данные с пробелом, в качестве разделителя:
xoadmin backup bin ...
LinuxCamp
👍26✍7❤🔥6❤4
Раскрываем завесу тайн над устройствами
Для многих пользователей Linux долгое время может быть неясна суть устройств, каталогов dev/sys и различий между ними. Хорошо бы в этом немного разбираться, т.к. иногда приходится работать с дисками, разделами, tty, pty.
Что еще за dev?
В каталоге dev находятся файлы, которые являются интерфейсом взаимодействия ядра с физическими (принтер, камера, SSD и т.д.) и виртуальными (null, urandom, tty и т.д.) устройствами, подключенными к системе и готовыми к работе.
Сами файлы драйверами не являются, при работе с ними ядро отказывается от своих обычных файловых операций и использует необходимые драйвера.
Устройства бывают разных типов:
Обратите внимание на первый символ каждой строки. Если он входит в перечисление: b (block), c (character), p (pipe) или s (socket), то файл является устройством.
Сейчас кратко рассмотрим типы, без излишнего углубления, т.к. знать тут все на начальных порах необязательно.
Блочные устройства
Доступ к данным блочного устройства происходит фиксированными частями определенного размера. Устройство sda1 в приведенном примере - это дисковое устройство, которое является типом блочного устройства.
Обычно устройства данного типа характеризуются возможностью хостить файловую систему: HDD, SSD, USB накопители.
Символьные устройства
К символьным устройствам можно обращаться как к потокам данных. Чтение и запись происходит посимвольно либо небольшими блоками за раз. Примерами устройств являются: принтер, мышь, клавиатура, tty, null.
Именованный конвейер
По структуре такой же, как символьное устройство, но с другим процессом на конце потока ввода-вывода вместо драйвера ядра.
Фактически - это обыкновенный pipe |, у которого есть имя, которое можно указывать всюду, где требуется файл.
Сокет
Специальный интерфейс для межпроцессной связи. Они позволяют обмениваться данными через сетевые соединения или внутри одного компьютера (с помощью Unix-сокетов).
Номера major и minor
К блочным и символьным устройствам применимы специальные номера major и minor, которые ядро использует для идентификации:
Major (8) говорит о том, какой драйвер использовать, minor (1) - описывает номер устройства, для которого используется драйвер, подвязанный к номеру major.
Скажем, HDD может быть разбит на несколько разделов, каждый из которых будет иметь отдельный номер minor и единый major, т.к. один и тот же драйвер используется для каждого раздела.
Файлы в каталоге dev не являются постоянными, они создаются либо в момент старта системы либо при подключении и определении устройства. Создаются демонами: udevd или mdevd. Как раз эти программы отвечают за определение устройства и подгрузку соответсвующих драйверов.
Драйвер - программа, которая позволяет нашей ОС общаться с оборудованием. Представлен он может быть, например, динамически подгружаемым модулем ядра либо его статической частью. Подключили мышку, нужен драйвер, который позволить с ней работать.
LinuxCamp
Для многих пользователей Linux долгое время может быть неясна суть устройств, каталогов dev/sys и различий между ними. Хорошо бы в этом немного разбираться, т.к. иногда приходится работать с дисками, разделами, tty, pty.
Что еще за dev?
В каталоге dev находятся файлы, которые являются интерфейсом взаимодействия ядра с физическими (принтер, камера, SSD и т.д.) и виртуальными (null, urandom, tty и т.д.) устройствами, подключенными к системе и готовыми к работе.
Сами файлы драйверами не являются, при работе с ними ядро отказывается от своих обычных файловых операций и использует необходимые драйвера.
Устройства бывают разных типов:
$ ls -l
brw-rw---- 1 root disk 8, 1 Sep 6 08:37 sda1
crw-rw-rw- 1 root root 1, 3 Sep 6 08:37 null
prw-r--r-- 1 root root 0 Mar 3 19:17 fdata
srw-rw-rw- 1 root root 0 Dec 18 07:43 log
Обратите внимание на первый символ каждой строки. Если он входит в перечисление: b (block), c (character), p (pipe) или s (socket), то файл является устройством.
Сейчас кратко рассмотрим типы, без излишнего углубления, т.к. знать тут все на начальных порах необязательно.
Блочные устройства
Доступ к данным блочного устройства происходит фиксированными частями определенного размера. Устройство sda1 в приведенном примере - это дисковое устройство, которое является типом блочного устройства.
Обычно устройства данного типа характеризуются возможностью хостить файловую систему: HDD, SSD, USB накопители.
Символьные устройства
К символьным устройствам можно обращаться как к потокам данных. Чтение и запись происходит посимвольно либо небольшими блоками за раз. Примерами устройств являются: принтер, мышь, клавиатура, tty, null.
Именованный конвейер
По структуре такой же, как символьное устройство, но с другим процессом на конце потока ввода-вывода вместо драйвера ядра.
Фактически - это обыкновенный pipe |, у которого есть имя, которое можно указывать всюду, где требуется файл.
Сокет
Специальный интерфейс для межпроцессной связи. Они позволяют обмениваться данными через сетевые соединения или внутри одного компьютера (с помощью Unix-сокетов).
Номера major и minor
К блочным и символьным устройствам применимы специальные номера major и minor, которые ядро использует для идентификации:
8, 1 Sep 6 08:37 sda1
Major (8) говорит о том, какой драйвер использовать, minor (1) - описывает номер устройства, для которого используется драйвер, подвязанный к номеру major.
Скажем, HDD может быть разбит на несколько разделов, каждый из которых будет иметь отдельный номер minor и единый major, т.к. один и тот же драйвер используется для каждого раздела.
Файлы в каталоге dev не являются постоянными, они создаются либо в момент старта системы либо при подключении и определении устройства. Создаются демонами: udevd или mdevd. Как раз эти программы отвечают за определение устройства и подгрузку соответсвующих драйверов.
Драйвер - программа, которая позволяет нашей ОС общаться с оборудованием. Представлен он может быть, например, динамически подгружаемым модулем ядра либо его статической частью. Подключили мышку, нужен драйвер, который позволить с ней работать.
LinuxCamp
1👍47🔥13❤🔥3❤2
Не самый стандартный способ использовать syslog
Расскажу историю о том, как очередная хотелка заказчика заставила меня немного под другим углом взглянуть на syslog. И так, какой самый привычный вам способ обращаться к файлу /var/log/syslog?
Если вы штатный пользователь, то, вероятно, хотите провести мониторинг логов и выяснить, где что-то пошло не так. Для этого вы пойдете искать сообщения от "подозреваемого" сервиса.
Если вы разработчик, то можете захотеть направлять туда отладочную информацию. А-ля, подключение к VPN прошло успешно, сертификат принят и т.д. Если вы пишите демон, за которым не может быть закреплен терминал, то вариант с syslog - вынужденная мера.
Так вот, пришел заказчик и говорит: "Нашим пользователям абсолютно неясна причина, по которой подключение к VPN было отклонено. То ли это ошибка в конфигах, то ли сертификат просрочен. Хочется, чтобы на рабочий стол выводилось уведомление с подробным описанием ошибки".
Принято, сделаем. Первое, что пришло в голову - использовать libnotify. Библиотека позволяет через код собирать уведомления и направлять их специальному демону (зависит от окружения) для вывода. Утилита "notify-send" демонстрирует работу API:
Выяснить, какой процесс выступает в роли демона для уведомлений, можно следующим образом:
Короче говоря, подход этот оказался нерабочим, т.к. коды ошибок формировал демон вне пользовательской сессии, а libnotify требовал в окружении процесса переменную DBUS_SESSION_BUS_ADDRESS, которая отсутствовала...
Частично о проблеме можно почитать тут.
Дальше либо добавлять новые коды ошибок, патчить 3 утилиты "strongswan -> network manager -> nm-applet" и выводить сообщения через nm-applet, либо использовать сторонний ПОЛЬЗОВАТЕЛЬСКИЙ сервис, который бы отслеживал логи и по ним собирал уведомления.
Благо, в дистрах обычно присутствуем подсистема событий, которая работает совместно с демоном syslog-ng и позволяет реагировать на определенные логи.
В результате, задача решилась следующим образом:
1) проработан ряд конфигов, по которым производился парсинг сообщений syslog и настройка уведомлений;
2) в код strongswan добавлен вывод отладочной информации (в централизованном формате) в файл /var/log/syslog:
3) в правила "роспакоуки" deb пакета добавлены инструкции установки конфигов в системные директории;
С высоты текущего полета не сказал бы, что решение супер гибкое и легко масштабируемое, но правки оказались минимальными и безопасными, что особенно важно при работе с таким софтом, как strongswan.
LinuxCamp
Расскажу историю о том, как очередная хотелка заказчика заставила меня немного под другим углом взглянуть на syslog. И так, какой самый привычный вам способ обращаться к файлу /var/log/syslog?
Если вы штатный пользователь, то, вероятно, хотите провести мониторинг логов и выяснить, где что-то пошло не так. Для этого вы пойдете искать сообщения от "подозреваемого" сервиса.
Если вы разработчик, то можете захотеть направлять туда отладочную информацию. А-ля, подключение к VPN прошло успешно, сертификат принят и т.д. Если вы пишите демон, за которым не может быть закреплен терминал, то вариант с syslog - вынужденная мера.
Так вот, пришел заказчик и говорит: "Нашим пользователям абсолютно неясна причина, по которой подключение к VPN было отклонено. То ли это ошибка в конфигах, то ли сертификат просрочен. Хочется, чтобы на рабочий стол выводилось уведомление с подробным описанием ошибки".
Принято, сделаем. Первое, что пришло в голову - использовать libnotify. Библиотека позволяет через код собирать уведомления и направлять их специальному демону (зависит от окружения) для вывода. Утилита "notify-send" демонстрирует работу API:
$ notify-send header body
Выяснить, какой процесс выступает в роли демона для уведомлений, можно следующим образом:
$ NOTIFD_ID=$(qdbus org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetConnectionUnixProcessID org.freedesktop.Notifications)
$ ps aux | grep $NOTIFD_ID
Короче говоря, подход этот оказался нерабочим, т.к. коды ошибок формировал демон вне пользовательской сессии, а libnotify требовал в окружении процесса переменную DBUS_SESSION_BUS_ADDRESS, которая отсутствовала...
Частично о проблеме можно почитать тут.
Дальше либо добавлять новые коды ошибок, патчить 3 утилиты "strongswan -> network manager -> nm-applet" и выводить сообщения через nm-applet, либо использовать сторонний ПОЛЬЗОВАТЕЛЬСКИЙ сервис, который бы отслеживал логи и по ним собирал уведомления.
Благо, в дистрах обычно присутствуем подсистема событий, которая работает совместно с демоном syslog-ng и позволяет реагировать на определенные логи.
В результате, задача решилась следующим образом:
1) проработан ряд конфигов, по которым производился парсинг сообщений syslog и настройка уведомлений;
2) в код strongswan добавлен вывод отладочной информации (в централизованном формате) в файл /var/log/syslog:
DBG1(DBG_CFG, "type=STRONGSWAN action='CONNECTION ERROR REPORT' body='%s'", "Не удалось загрузить сертификат клиента");
3) в правила "роспакоуки" deb пакета добавлены инструкции установки конфигов в системные директории;
С высоты текущего полета не сказал бы, что решение супер гибкое и легко масштабируемое, но правки оказались минимальными и безопасными, что особенно важно при работе с таким софтом, как strongswan.
LinuxCamp
🔥24👍13❤🔥3🤔3
Что такое /dev/null и почему туда направляют данные?
Если вы активно работаете в командной строке, то, вероятно, использовали файл /dev/null для следующих целей:
1) убрать из вывода всю ненужную инфу (предупреждения, ошибки и т.д.):
2) передать утилите пустой ресурс в качестве аргумента. Делаться это может с целью исключения пользовательских и системных конфигов и применения дефолтных настроек на стороне программы:
3) полностью очистить файл:
Окей, принято, а чем является этот самый /dev/null?
В сущности - это cимвольное псевдо-устройство, которое создается на этапе запуска системы и работает с потоками данных:
О типе устройства говорит первый бит режима файла "c (character)".
Ресурс удаляет все записанное в него и возвращает при чтении EOF (End of File). Когда мы взаимодействуем с /dev/null, неявно отрабатывает специальный драйвер ядра, в который и зашита логика.
Если интересно, можно порыться в исходниках с реализацией: drivers/char/mem.c. Код имеет отношение не только к /dev/null, но и к другим символьным устройствам.
Развернем более подробную информацию:
Этот вывод показывает, что файл имеет размер 0 байт, для него выделено 0 блоков на диске, дата создания = дата запуска системы:
Права доступа установлены таким образом, что любой может читать и записывать в него, но никто не может его выполнять:
Поскольку файл не исполняемый, мы не можем использовать конвейер |. Единственный способ — использовать перенаправление файлов ">, >>".
Думаю, этих знаний вам пока будет достаточно для того, чтобы комфортно пользоваться "трюками" этого устройства. До встречи)
LinuxCamp
Если вы активно работаете в командной строке, то, вероятно, использовали файл /dev/null для следующих целей:
1) убрать из вывода всю ненужную инфу (предупреждения, ошибки и т.д.):
$ find / -name "*.conf" 2>/dev/null
2) передать утилите пустой ресурс в качестве аргумента. Делаться это может с целью исключения пользовательских и системных конфигов и применения дефолтных настроек на стороне программы:
$ picom --config /dev/null
3) полностью очистить файл:
$ cat /dev/null > bigfile
Окей, принято, а чем является этот самый /dev/null?
В сущности - это cимвольное псевдо-устройство, которое создается на этапе запуска системы и работает с потоками данных:
$ ls -l
crw-rw-rw- 1 root root 1, 3 Sep 6 08:37 null
О типе устройства говорит первый бит режима файла "c (character)".
Ресурс удаляет все записанное в него и возвращает при чтении EOF (End of File). Когда мы взаимодействуем с /dev/null, неявно отрабатывает специальный драйвер ядра, в который и зашита логика.
Если интересно, можно порыться в исходниках с реализацией: drivers/char/mem.c. Код имеет отношение не только к /dev/null, но и к другим символьным устройствам.
Развернем более подробную информацию:
$ stat /dev/null
File: /dev/null
Size: 0 Blocks: 0 IO Block: 4096 character special file
Access: (0666/crw-rw-rw-) Uid: (0/ root) Gid: (0/ root)
Access: 2025-01-25 14:42:20.101000002 +0300
...
Этот вывод показывает, что файл имеет размер 0 байт, для него выделено 0 блоков на диске, дата создания = дата запуска системы:
$ who -b
system boot 2025-01-25 14:42
Права доступа установлены таким образом, что любой может читать и записывать в него, но никто не может его выполнять:
$ echo hello | /dev/null
-bash2: /dev/null: Permission denied
Поскольку файл не исполняемый, мы не можем использовать конвейер |. Единственный способ — использовать перенаправление файлов ">, >>".
Думаю, этих знаний вам пока будет достаточно для того, чтобы комфортно пользоваться "трюками" этого устройства. До встречи)
LinuxCamp
👍42🔥11❤🔥3❤2
Познаем brace expansion
Продолжаем серию постов по спецсимволам оболочки: (), $(), []. Сегодня говорим про расширение фигурных скобок (brace expansion).
Символы {} позволяют развернуть выражение внутри в последовательность аргументов:
Внутрь скобок может быть добавлен опциональный 3 параметр. С ним выражение {x..y..z} генерирует значения от x до y с шагом z:
Расширение {}, в отличие от команды seq, может создавать последовательность букв:
При желании, можем добавить шаг, например, чтобы выводить символ через 1 в диапазоне от A до P:
Использование перечислений
Если нам не требуется вычисление последовательности, можно поместить внутрь скобок перечисление:
Вариант практического применения данной техники - получение различий между файлами:
Прогерам бывает приходится составлять пачи по результатам команды diff и расширение тут очень кстати - не нужно дважды вводить почти идентичный путь.
Немного отойдем от общего вида паттерна, оставим 1 аргумент и создадим бэкап файла:
Если перед запятой отсутствует значение, подстановка в этом месте пропускается, но вывод, при наличии текста вне {}, выполняется:
Предупреждение: не ставьте пробелы внутри скобок иначе расширение не отработает:
Изменение формата вывода
Как можно заметить из примеров выше, вывод всегда записывается в виде одной строки, разделенной пробелами. Изменить это можно, перенаправив его другим командам, таким как tr:
Теперь можно создать псевдоним, который печатает n букву английского алфавита:
Фигурные скобки vs квадратные
Квадратные скобки — это оператор сопоставления имен файлов с шаблоном. Фигурные, в свою очередь, не имеют к файлам никакого отношения. Они просто просчитывают и возвращают последовательность значений.
К примеру, у нас в каталоге содержится 4 файла:
Используем сопоставление по шаблону в диапазоне от 1 до 9:
Все отработало без ошибок, оболочка нашла файлы, которые подходят под шаблон и передала их в качестве аргументов.
Теперь в этом же диапазоне используем расширение {}:
Оболочка без разбора подставила всю последовательность. Что-то нашлось, что-то нет.
Группировка расширений
Спокойно можно использовать группу символов {} в 1 выражении, чтобы, например, создать несколько файлов с разными расширеними:
Bash берёт каждую букву из первого набора и комбинирует её со всеми вариантами второго.
Либо еще опция - использовать вложенность. Бывает полезно при создании группы подкаталогов:
LinuxCamp
Продолжаем серию постов по спецсимволам оболочки: (), $(), []. Сегодня говорим про расширение фигурных скобок (brace expansion).
Символы {} позволяют развернуть выражение внутри в последовательность аргументов:
$ echo {1..10}
1 2 3 4 5 6 7 8 9 10
$ echo {10..1}
10 9 8 7 6 5 4 3 2 1
Внутрь скобок может быть добавлен опциональный 3 параметр. С ним выражение {x..y..z} генерирует значения от x до y с шагом z:
$ echo {1..501..100}
1 101 201 301 401 501
$ echo {501..1..100}
501 401 301 201 101 1
Расширение {}, в отличие от команды seq, может создавать последовательность букв:
$ echo {A..P}
A B C D E F G H I J K L M N O P
При желании, можем добавить шаг, например, чтобы выводить символ через 1 в диапазоне от A до P:
$ echo {A..P..2}
A C E G I K M O
Использование перечислений
Если нам не требуется вычисление последовательности, можно поместить внутрь скобок перечисление:
$ mkdir ~/Sources/{test1,test2,test3}
Вариант практического применения данной техники - получение различий между файлами:
$ diff {orig,patched}/path/to/prog.c
Прогерам бывает приходится составлять пачи по результатам команды diff и расширение тут очень кстати - не нужно дважды вводить почти идентичный путь.
Немного отойдем от общего вида паттерна, оставим 1 аргумент и создадим бэкап файла:
$ cp -p file.txt{,.bak}
$ ls
file.txt file.txt.bak
Если перед запятой отсутствует значение, подстановка в этом месте пропускается, но вывод, при наличии текста вне {}, выполняется:
$ echo file.txt{,.bak}
file.txt file.txt.bak
Предупреждение: не ставьте пробелы внутри скобок иначе расширение не отработает:
$ echo file{1.. 2}.txt
file{1.. 2}.txt
Изменение формата вывода
Как можно заметить из примеров выше, вывод всегда записывается в виде одной строки, разделенной пробелами. Изменить это можно, перенаправив его другим командам, таким как tr:
$ echo {A..P..2} | tr -d " "
ACEGIKMO
Теперь можно создать псевдоним, который печатает n букву английского алфавита:
$ alias nth="echo {A..Z} | tr -d ' ' | cut -c"
$ nth 10
J
Фигурные скобки vs квадратные
Квадратные скобки — это оператор сопоставления имен файлов с шаблоном. Фигурные, в свою очередь, не имеют к файлам никакого отношения. Они просто просчитывают и возвращают последовательность значений.
К примеру, у нас в каталоге содержится 4 файла:
$ ls
file1.txt file2.txt file3.txt file4.txt
Используем сопоставление по шаблону в диапазоне от 1 до 9:
$ ls file[1-9].txt
file1.txt file2.txt file3.txt file4.txt
Все отработало без ошибок, оболочка нашла файлы, которые подходят под шаблон и передала их в качестве аргументов.
Теперь в этом же диапазоне используем расширение {}:
$ ls file{1..9}.txt
ls: cannot access 'file5.txt': No such file or directory
ls: cannot access 'file6.txt': No such file or directory
...
file1.txt file2.txt file3.txt file4.txt
Оболочка без разбора подставила всю последовательность. Что-то нашлось, что-то нет.
Группировка расширений
Спокойно можно использовать группу символов {} в 1 выражении, чтобы, например, создать несколько файлов с разными расширеними:
$ touch {a,b,c}.{hpp,cpp}
$ ls
a.cpp a.hpp b.cpp b.hpp c.cpp c.hpp
Bash берёт каждую букву из первого набора и комбинирует её со всеми вариантами второго.
Либо еще опция - использовать вложенность. Бывает полезно при создании группы подкаталогов:
$ mkdir -p {source,help{/pages,/yelp,/images}}
$ tree
.
├── help
│ ├── images
│ ├── pages
│ └── yelp
└── source
LinuxCamp
👍55🔥23❤8👎1🤔1💘1
Копирование и вставка "по уму"
Вы наверняка умеете работать с копированием и вставкой через сочетания клавиш: Ctrl + C, Ctrl + V.
Но знаете ли вы, что можете более эффективно обрабатывать содержимое буфера обмена прямо из командной строки?
Буфер обмена — это общее название для блока памяти, в котором временно находится скопированная информация.
Большинство X11 окружений рабочего стола поддерживают два варианта буфера:
1. Системный буфер обмена (clipboard). Когда вы выполняете операции "cut/copy" через горячие клавиши, содержимое попадает в этот буфер. После вставки информация извлекается.
2. Первичный буфер обмена (primary selection). Запись происходит, когда вы мышью выделяете текст в определенных приложениях. Для извлечения используется нажатие на колесо.
Если у кого в наличии только тачпадам, следует одновременно нажать левую и правую кнопки для вставки текста.
Обычно эти буферы не связаны и хранящиеся в них данные не влияют друг на друга. Записываем что-то в clipboard, primary selection остается нетронутым.
Подключение буферов к потокам
В Linux есть команда xclip, которая соединяет X-буферы обмена с потоками stdin и stdout.
Благодаря ей можно заполнять буферы информацией либо извлекать ее через конвейер и перенаправление файла.
По умолчанию команда читает stdout и записывает его в первичный буфер:
Теперь выведем текст в stdout, перенаправим его в файл и передадим команде wc:
Очистим первичный буфер обмена, поместив в него пустую строку:
Параметр "-n" важен, так как в противном случае echo выведет в stdout символ новой строки "\n", который окажется в первичном буфере обмена.
Команда поддерживает явное указание буфера. Чтобы скопировать текст в системный буфер обмена вместо первичного, запустим xclip с параметром "-selection clipboard":
Теперь вы можете либо использовать комбинации клавиш для вывода либо просто флаг "-o".
При необходимости параметры xclip могут быть сокращены "-selection clipboard == -sel c"
Немного практики
Чтобы дополнительно облегчить себе жизнь, можно создать на xclip несколько алиасов:
Теперь, допустим, нам нужно установить определенный deb пакет, предварительно определив его среди общей массы:
Отлично, копируем название в буфер, затем выполняем вставку после целевой команды:
LinuxCamp
Вы наверняка умеете работать с копированием и вставкой через сочетания клавиш: Ctrl + C, Ctrl + V.
Но знаете ли вы, что можете более эффективно обрабатывать содержимое буфера обмена прямо из командной строки?
Буфер обмена — это общее название для блока памяти, в котором временно находится скопированная информация.
Большинство X11 окружений рабочего стола поддерживают два варианта буфера:
1. Системный буфер обмена (clipboard). Когда вы выполняете операции "cut/copy" через горячие клавиши, содержимое попадает в этот буфер. После вставки информация извлекается.
2. Первичный буфер обмена (primary selection). Запись происходит, когда вы мышью выделяете текст в определенных приложениях. Для извлечения используется нажатие на колесо.
Если у кого в наличии только тачпадам, следует одновременно нажать левую и правую кнопки для вставки текста.
Обычно эти буферы не связаны и хранящиеся в них данные не влияют друг на друга. Записываем что-то в clipboard, primary selection остается нетронутым.
Подключение буферов к потокам
В Linux есть команда xclip, которая соединяет X-буферы обмена с потоками stdin и stdout.
Благодаря ей можно заполнять буферы информацией либо извлекать ее через конвейер и перенаправление файла.
По умолчанию команда читает stdout и записывает его в первичный буфер:
$ xclip < myfile.txt
$ echo "Some cool text" | xclip
Теперь выведем текст в stdout, перенаправим его в файл и передадим команде wc:
$ xclip -o
Some cool text
$ xclip -o > file.txt
$ xclip -o | wc -w
3
Очистим первичный буфер обмена, поместив в него пустую строку:
$ echo -n | xclip
Параметр "-n" важен, так как в противном случае echo выведет в stdout символ новой строки "\n", который окажется в первичном буфере обмена.
Команда поддерживает явное указание буфера. Чтобы скопировать текст в системный буфер обмена вместо первичного, запустим xclip с параметром "-selection clipboard":
$ ls | grep scr | xclip -selection clipboard
$ xclip -selection clipboard -o
noscript.sh
Теперь вы можете либо использовать комбинации клавиш для вывода либо просто флаг "-o".
При необходимости параметры xclip могут быть сокращены "-selection clipboard == -sel c"
Немного практики
Чтобы дополнительно облегчить себе жизнь, можно создать на xclip несколько алиасов:
$ alias ccopy="xclip -sel c"
$ alias cpaste="xclip -sel c -o"
Теперь, допустим, нам нужно установить определенный deb пакет, предварительно определив его среди общей массы:
$ ls ~/Downloads | grep code
code_1.96.4-1736994636_arm64.deb
Отлично, копируем название в буфер, затем выполняем вставку после целевой команды:
$ ls ~/Downloads | grep code | ccopy
$ sudo dpkg -i ~/Downloads/$(cpaste)
LinuxCamp
👍46🔥16❤🔥3❤3🤷♂1👏1
Прокачиваемся в grep
При работе в командной строке невозможно обойтись без grep - очень полезная утилита для работы с текстом.
Сегодня мы рассмотрим несколько популярных опций, которые позволяют выполнять более продвинутую выборку.
Найти точное соответствие
Для того чтобы искать соответствия только целым словам, используйте флаг "-w":
Аналогичного результата можно добиться через регулярное выражение:
"\<" — начало слова.
"test" — искомый текст.
"\>" — конец слова.
Угловые скобки должны экранироваться, иначе они будут интерпретироваться как простые символы.
Игнорировать регистр
По умолчанию, grep чувствительна к регистру, что немного мешает поиску. Проблема решается путем добавления ключа "-i" к команде:
Вывод файлов с совпадениями
Используйте параметр "-l", чтобы вывести не сами строки, а только пути к файлам, в которых они содержатся:
Параметр "-r" отвечает за рекурсивный поиск - grep прошерстит не только 1 уровень каталога, а пойдет вглубь.
Поиск по нескольким параметрам
Для того, чтобы передать команде несколько вводных данных для определения совпадений, используется флаг "-e" перед каждым объектом поиска:
Эту команду система понимает, как "или-или" и выводит все вхождения указанных слов.
Использование регулярных выражений
Настоящая сила grep проявляется, когда вы переходите от сопоставления простых строк к сопоставлению шаблонов - регулярных выражений.
Выражения бывают 2 типов: basic и extended. Одна из особенностей второго типа заключается в том, что некоторые символы требуют экранирования для сохранности фич: ?, +, {, |, (, ), <, >.
Но можно обойтись просто добавлением флага "-E":
1. Квадратные скобки "[]" используются, чтобы провести проверку на соответствие одному из указанных символов:
Можем указать "-" для того, чтобы использовать диапазон значений:
2. Каретка "^" используется для поиска строк, которые начинаются с указанного шаблона. Давайте найдем совпадение всех строк, начинающихся с заглавной буквы:
3. Знак доллара "$" означает конец строки. В результат входят только те элементы, конец которых подходит под шаблон:
4. Точка "." обозначает любой одиночный символ, кроме новой строки. Регулярное выражение "....." обозначает любую строку, содержащую минимум 5 символов:
5. Вертикальная черта "|" выполняет роль логического оператора "ИЛИ":
В общем, регулярные выражения прекрасны и многообразны. Детальнее ознакомиться с ними можете по ссылке.
Экранирование
Иногда выражения приводят к неожиданным результатам.
Предположим, вы хотите найти в файле "myfile" только те строки, которые заканчиваются на ".sh".
Следующая команда выдаст неверный результат, поскольку точка — это регулярное выражение, означающее «любой символ»:
Чтобы обойти эту проблему, требуется экранировать спецсимвол:
Такое решение иногда становится громоздким. К счастью, можно заставить grep забыть о регулярных выражениях и искать буквально то, что мы указываем.
Для этого используется параметр (fixed) "-F":
LinuxCamp | #utils
При работе в командной строке невозможно обойтись без grep - очень полезная утилита для работы с текстом.
Сегодня мы рассмотрим несколько популярных опций, которые позволяют выполнять более продвинутую выборку.
Найти точное соответствие
Для того чтобы искать соответствия только целым словам, используйте флаг "-w":
$ ls
'test noscript.sh' test test_1 test_2
$ ls | grep -w test
test noscript.sh
test
Аналогичного результата можно добиться через регулярное выражение:
$ ls | grep "\<test\>"
test noscript.sh
test
"\<" — начало слова.
"test" — искомый текст.
"\>" — конец слова.
Угловые скобки должны экранироваться, иначе они будут интерпретироваться как простые символы.
Игнорировать регистр
По умолчанию, grep чувствительна к регистру, что немного мешает поиску. Проблема решается путем добавления ключа "-i" к команде:
ls | grep -i new
newFile
NewFile
Вывод файлов с совпадениями
Используйте параметр "-l", чтобы вывести не сами строки, а только пути к файлам, в которых они содержатся:
$ grep -r -l "libnma" /usr/share
/usr/share/doc/libnma-gtk4-0/copyright
Параметр "-r" отвечает за рекурсивный поиск - grep прошерстит не только 1 уровень каталога, а пойдет вглубь.
Поиск по нескольким параметрам
Для того, чтобы передать команде несколько вводных данных для определения совпадений, используется флаг "-e" перед каждым объектом поиска:
$ ls | grep -i -e new -e old
NewFile
newFile
oldFile
Эту команду система понимает, как "или-или" и выводит все вхождения указанных слов.
Использование регулярных выражений
Настоящая сила grep проявляется, когда вы переходите от сопоставления простых строк к сопоставлению шаблонов - регулярных выражений.
Выражения бывают 2 типов: basic и extended. Одна из особенностей второго типа заключается в том, что некоторые символы требуют экранирования для сохранности фич: ?, +, {, |, (, ), <, >.
Но можно обойтись просто добавлением флага "-E":
$ ls | grep -E "noscript|test"
1. Квадратные скобки "[]" используются, чтобы провести проверку на соответствие одному из указанных символов:
$ ls | grep "test[23]"
test2
test3
Можем указать "-" для того, чтобы использовать диапазон значений:
$ ls | grep "test[1-3]"
test2
test3
2. Каретка "^" используется для поиска строк, которые начинаются с указанного шаблона. Давайте найдем совпадение всех строк, начинающихся с заглавной буквы:
$ grep "^[A-Z]" myfile
A lot of text
Hello world
3. Знак доллара "$" означает конец строки. В результат входят только те элементы, конец которых подходит под шаблон:
$ grep "world$" myfile
Hello world
hello world
4. Точка "." обозначает любой одиночный символ, кроме новой строки. Регулярное выражение "....." обозначает любую строку, содержащую минимум 5 символов:
$ grep '.....' myfile
5. Вертикальная черта "|" выполняет роль логического оператора "ИЛИ":
$ ls | grep "noscript\|test"
noscript
test
В общем, регулярные выражения прекрасны и многообразны. Детальнее ознакомиться с ними можете по ссылке.
Экранирование
Иногда выражения приводят к неожиданным результатам.
Предположим, вы хотите найти в файле "myfile" только те строки, которые заканчиваются на ".sh".
Следующая команда выдаст неверный результат, поскольку точка — это регулярное выражение, означающее «любой символ»:
$ grep ".sh" myfile
noscript_name.sh
noscript_namesh
Чтобы обойти эту проблему, требуется экранировать спецсимвол:
$ grep "\.sh" myfile
noscript_name.sh
Такое решение иногда становится громоздким. К счастью, можно заставить grep забыть о регулярных выражениях и искать буквально то, что мы указываем.
Для этого используется параметр (fixed) "-F":
$ grep -F ".sh" myfile
noscript_name.sh
LinuxCamp | #utils
👍62🔥17❤9❤🔥3
Ничего лишнего, только head и tail
Утилиты head и tail можно назвать сестрами. Они обе позволяют просматривать только часть того, что поступило на вход: head показывает начало, а tail — конец.
Команды могут принимать входные данные либо с какого-то ресурса (файла) либо от других утилит через конвейер "|":
Если в команде head не указаны флаги, то по умолчанию выводятся первые 10 строк.
Для того, чтобы ограничить вывод и просмотреть N элементов, используем параметр "-n":
Параметр "-n" также можно использовать для того, чтобы вывести все содержимое, за исключением N последних строк. Для этого нужно использовать выражение вида "-n-N".
Если у нас всего 10 строк и требуется получить первые 3, сделаем:
Без проблем можно единовременно получить вывод с нескольких файлов. Достаточно перечислить названия через пробел:
Если вывод названий файлов и разделителей "\n" нам не нужен, используем флаг "-q":
Команда tail печатает последние строки файла — по умолчанию также 10:
Принцип использования команды tail практически аналогичен head. Если хотим ограничить вывод последними 3 строками, добавляем флаг "-n":
Если поставить перед номером знак "+", печать начнется со строки этого номера и продолжится до конца файла:
Обе команды вместе
Объединяйте head и tail, чтобы напечатать любой диапазон строк.
Например, чтобы вывести строки c 4 по 7, используем head для элементов "1-7" и tail для "7-4":
В общем, чтобы отобразить строки от M до N, извлеките первые N строк с помощью head, затем выведите последние N-M+1 строк с помощью tail.
Чуток жизненной практики
Последнее время частенько приходится работать с патчами - накладывать их на приложения через quilt и снимать.
Нужно было наложить на утилиту только 10 патчей из 20. Для того, чтобы поработать с диапазоном, использовал команду head:
1) quilt series выводит список патчей в столбец;
2) head -n 10 отображает только первые 10 строк;
3) xargs -L1 quilt push выполняет команду для каждого отдельного патча;
LinuxCamp | #utils
Утилиты head и tail можно назвать сестрами. Они обе позволяют просматривать только часть того, что поступило на вход: head показывает начало, а tail — конец.
Команды могут принимать входные данные либо с какого-то ресурса (файла) либо от других утилит через конвейер "|":
$ head test
Line 1
Line 2
Line 3
...
$ ls | head
adduser.conf
alsa
alternatives
...
Если в команде head не указаны флаги, то по умолчанию выводятся первые 10 строк.
Для того, чтобы ограничить вывод и просмотреть N элементов, используем параметр "-n":
$ head -n2 test
Line 1
Line 2
Параметр "-n" также можно использовать для того, чтобы вывести все содержимое, за исключением N последних строк. Для этого нужно использовать выражение вида "-n-N".
Если у нас всего 10 строк и требуется получить первые 3, сделаем:
$ head -n-7 test
Line 1
Line 2
Line 3
Без проблем можно единовременно получить вывод с нескольких файлов. Достаточно перечислить названия через пробел:
$ head -n2 test test2
==> test <==
Line 1
Line 2
==> test2 <==
Line 11
Line 12
Если вывод названий файлов и разделителей "\n" нам не нужен, используем флаг "-q":
$ head -n2 -q test test2
Line 1
Line 2
Line 11
Line 12
Команда tail печатает последние строки файла — по умолчанию также 10:
$ tail test
Line 1
Line 2
Line 3
...
Принцип использования команды tail практически аналогичен head. Если хотим ограничить вывод последними 3 строками, добавляем флаг "-n":
$ tail -n3 test
Line 8
Line 9
Line 10
Если поставить перед номером знак "+", печать начнется со строки этого номера и продолжится до конца файла:
$ tail -n+9 test
Line 9
Line 10
Обе команды вместе
Объединяйте head и tail, чтобы напечатать любой диапазон строк.
Например, чтобы вывести строки c 4 по 7, используем head для элементов "1-7" и tail для "7-4":
$ head -n7 test | tail -n4
Line 4
Line 5
Line 6
Line 7
В общем, чтобы отобразить строки от M до N, извлеките первые N строк с помощью head, затем выведите последние N-M+1 строк с помощью tail.
Чуток жизненной практики
Последнее время частенько приходится работать с патчами - накладывать их на приложения через quilt и снимать.
Нужно было наложить на утилиту только 10 патчей из 20. Для того, чтобы поработать с диапазоном, использовал команду head:
$ quilt series | head -n 10 | xargs -L1 quilt push
1) quilt series выводит список патчей в столбец;
2) head -n 10 отображает только первые 10 строк;
3) xargs -L1 quilt push выполняет команду для каждого отдельного патча;
LinuxCamp | #utils
👍34🔥8❤4❤🔥1
Прокачиваемся в find
Поиск файлов и каталогов через cli бывает гораздо более эффективен и гибок, нежели чем через GUI файловых менеджеров.
Команда find, как и grep, используется супер часто в командной строке. Она рекурсивно выводит пути к найденным файлам, спускаясь вглубь по иерархии.
Утилита имеет такой синтаксис:
Параметры - дополнительные опции, например, глубина поиска, фильтр по имени и т.д;
Действие - что будет выполнено с результатами поиска;
По синтаксису выше найдем пустые каталоги в tmp:
Детально ознакомиться с параметрами и прочей петрушкой можете по ссылке.
Поиск по типу файла
Флаг "-type" позволяет искать файлы по типу, среди которых:
1) f – простые файлы;
2) d – каталоги;
3) l – символические ссылки;
4) b – блочные устройства (dev);
5) c – символьные устройства (dev);
6) p – именованные каналы;
7) s – сокеты;
Перечисляем только каталоги:
Поиск по размеру файла
Флаг "-size" позволяет произвести фильтрацию по размеру.
Выведем все файлы более 1 Гб (+1G):
"+" — поиск файлов больше заданного размера;
"-" — поиск файлов меньше заданного размера;
Отсутствие знака — поиск по полному совпадению с заданным размером;
Единицы измерения файлов: c (байт), k (Кбайт), M (Мбайт), G (Гбайт).
Поиск пустых файлов и каталогов
Параметр "-empty" позволяет найти пустые ресурсы:
Не учитывать регистр при поиске
Если опция "-name" чувствительна к регистру, то "-iname" наоборот:
Несколько каталогов
Для поиска по нескольким каталогам просто используем перечисление:
Поиск по правам доступа
Команда нам позволяет искать ресурсы по определенной маске прав, например, 0664:
Вместо числового представления маски можно использовать символьное для: u (user) g (group) и o (other).
Выполним поиск файлов доступных владельцу для чтения/записи:
Чтобы немного въехать в суть прав доступа, можно просмотреть вот этот пост.
Ограничение глубины поиска
Если нам нужно указать максимальную глубину поиска, используем "-maxdepth".
Следующий запуск find пройдется только по самому верхнему уровню указанного каталога:
Операторы
Для инвертирования шаблона либо объединения можно применять операторы: and, or, not.
Флаг "-and" обычно можно опустить, т.к. он ставится по дефолту.
Найдем файлы, которые не соответствуют шаблону:
Либо найдем все файлы, начинающиеся на "test", но без расширения "php":
Можем также объединить несколько условий и найти ресурсы, которые принадлежат "xoadmin" и имеют размер "< 100 байт":
Если нужно учесть принадлежность к еще какому-нибудь пользователю, используем "or":
Действия
К команде можно добавить действия, которые будут выполнены с результатами поиска:
1) -delete: удаляет результаты поиска;
2) -ls: выводит доп информацию;
3) -print: показывает полный путь к найденным файлам (стоит по умолчанию);
4) -exec: выполняет указанную команду для найденных ресурсов;
Тут мы удаляем все пустые файлы и каталоги одним вызовом "rm -rf".
Можем через exec найти файлы и прочитать их:
Вместо {} подставляется путь к файлу. Если команда оканчивается на "\;", значит она будет выполнена для каждой строки с результатом.
LinuxCamp | #utils
Поиск файлов и каталогов через cli бывает гораздо более эффективен и гибок, нежели чем через GUI файловых менеджеров.
Команда find, как и grep, используется супер часто в командной строке. Она рекурсивно выводит пути к найденным файлам, спускаясь вглубь по иерархии.
Утилита имеет такой синтаксис:
find каталог параметры действие
Параметры - дополнительные опции, например, глубина поиска, фильтр по имени и т.д;
Действие - что будет выполнено с результатами поиска;
По синтаксису выше найдем пустые каталоги в tmp:
$ find /tmp -type d -empty -print
Детально ознакомиться с параметрами и прочей петрушкой можете по ссылке.
Поиск по типу файла
Флаг "-type" позволяет искать файлы по типу, среди которых:
1) f – простые файлы;
2) d – каталоги;
3) l – символические ссылки;
4) b – блочные устройства (dev);
5) c – символьные устройства (dev);
6) p – именованные каналы;
7) s – сокеты;
Перечисляем только каталоги:
$ find . -type d
.
./.ssh
./.cache
Поиск по размеру файла
Флаг "-size" позволяет произвести фильтрацию по размеру.
Выведем все файлы более 1 Гб (+1G):
$ find . -size +1G
./android-studio-ide-183.5692245-mac.dmg
"+" — поиск файлов больше заданного размера;
"-" — поиск файлов меньше заданного размера;
Отсутствие знака — поиск по полному совпадению с заданным размером;
Единицы измерения файлов: c (байт), k (Кбайт), M (Мбайт), G (Гбайт).
Поиск пустых файлов и каталогов
Параметр "-empty" позволяет найти пустые ресурсы:
$ find . -type d -empty
./datafiles
Не учитывать регистр при поиске
Если опция "-name" чувствительна к регистру, то "-iname" наоборот:
$ find . -name "new*"
./new test file
./newFile
$ find . -iname "new*"
./NewFile
./new test file
./newFile
Несколько каталогов
Для поиска по нескольким каталогам просто используем перечисление:
find ./dir1 ./dir2 -type f -name "*.c"
Поиск по правам доступа
Команда нам позволяет искать ресурсы по определенной маске прав, например, 0664:
$ find . -type f -perm 0664
Вместо числового представления маски можно использовать символьное для: u (user) g (group) и o (other).
Выполним поиск файлов доступных владельцу для чтения/записи:
$ find /etc -perm /u=rw
Чтобы немного въехать в суть прав доступа, можно просмотреть вот этот пост.
Ограничение глубины поиска
Если нам нужно указать максимальную глубину поиска, используем "-maxdepth".
Следующий запуск find пройдется только по самому верхнему уровню указанного каталога:
$ find /etc -maxdepth 1
Операторы
Для инвертирования шаблона либо объединения можно применять операторы: and, or, not.
Флаг "-and" обычно можно опустить, т.к. он ставится по дефолту.
Найдем файлы, которые не соответствуют шаблону:
$ find . -not -name "test*"
Либо найдем все файлы, начинающиеся на "test", но без расширения "php":
$ find . -name "test" -not -name "*.php"
Можем также объединить несколько условий и найти ресурсы, которые принадлежат "xoadmin" и имеют размер "< 100 байт":
$ find . -user xoadmin -and -size -100c -type f
Если нужно учесть принадлежность к еще какому-нибудь пользователю, используем "or":
$ find . \( -user xoadmin -or -user vasya \) -and -size -100c -type f
Действия
К команде можно добавить действия, которые будут выполнены с результатами поиска:
1) -delete: удаляет результаты поиска;
$ find . -empty -delete
2) -ls: выводит доп информацию;
3) -print: показывает полный путь к найденным файлам (стоит по умолчанию);
4) -exec: выполняет указанную команду для найденных ресурсов;
$ find . -empty -exec rm -rf {} +
Тут мы удаляем все пустые файлы и каталоги одним вызовом "rm -rf".
Можем через exec найти файлы и прочитать их:
$ find . -type f -exec cat {} \;
Вместо {} подставляется путь к файлу. Если команда оканчивается на "\;", значит она будет выполнена для каждой строки с результатом.
LinuxCamp | #utils
👍48🔥9⚡8❤🔥4❤1👏1
Прокачиваемся в cp
У вас хоть одна пользовательская сессия проходит без копирования файлов?) В общем-то для этого мы и используем команду cp, в которой немало полезных опций.
Начнем с простого. Для копирования файлов команда имеет 2 типа синтаксиса:
1) с сохранением названия - с указанием каталога;
2) без сохранения - с указанием нового имени файла;
Сразу же скину ссылку на полную информацию о команде. Далее мы рассмотрим основные кейсы.
Копирование каталога
Для копирования каталогов нужно использовать опцию "-r":
Тут ме переносим весь каталог вместе с его наполнением.
Если нет полной уверенности в том, что каталог "dest" существует, можно добавить флаг "-t" для вывода предупреждения:
Копирование в этом случае выполнено не будет и каталог не будет создан.
Копирование содержимого каталога
Для того, чтобы перенести только содержимое директории, а не ее саму, используем:
Но есть нюансик... Это так работает только, если no_dest ранее не существовал. Если каталог назначения существует, то в нем будет создан src.
Для того чтобы избежать такого поведения можно использовать опцию "-T":
Как вариант, еще можно решить задачу использованием шаблона поиска:
Однако в этом случае скрытые файлы скопированы не будут. Ну и это не проблема особо:
Обработка существующих файлов
По умолчанию, если файл каталоге назначения уже существует, он будет перезаписан. Если вы хотите, чтобы утилита спросила вас, стоит ли его перезаписывать, используйте флаг "-i":
С помощью опции "-n" можно отключить перезапись существующих ресурсов:
Создание бэкапов
Для существующих файлов можно cделать резервную копию с помощью опции "-b". Если использовать этот флаг, то в конце названия файла резервной копии будет добавлен символ тильды "~":
При использовании параметра "--backup" можно настроить имя резервной копии. Вот доступные варианты:
1) none - резервная копия не делается;
2) numbered - к имени файла будет добавляться номер;
3) simple - в конец файла будет добавлен знак "~";
4) existing - если в целевой директории уже есть бэкапы, то будет использоваться аналогичный им тип нейминга;
Чтобы использовать номер в имени бэкапа используйте:
Ещё один вариант обработки существующих файлов - заменять только, если изначальный новее.
Для этого нужно использовать опцию "-u":
Копирование ссылок
По умолчанию жесткие и символические ссылки копируются как обычные файлы, сохраняя содержимое ресурса, к которому были подвязаны:
Если вы хотите, чтобы символические ссылки копировались, сохраняя свой тип, нужно использовать опцию "-P":
Ток, пожалуйста, не забывайте проверять путь к оригиналу на корректность - в примере выше ссылка поломана.
Для жестких ссылок существует другой подход. Если вы хотите, чтобы она осталась собой после копирования, нужно использовать опцию "-l":
Сохранение атрибутов
По умолчанию cp обновляет временные метки и атрибуты прав доступа файлов при копировании.
Иногда может возникнуть необходимость их сохранить. Для этого используем "--preserve":
LinuxCamp | #utils
У вас хоть одна пользовательская сессия проходит без копирования файлов?) В общем-то для этого мы и используем команду cp, в которой немало полезных опций.
Начнем с простого. Для копирования файлов команда имеет 2 типа синтаксиса:
1) с сохранением названия - с указанием каталога;
$ cp ./src/file ./dest/
2) без сохранения - с указанием нового имени файла;
$ cp ./src/file ./dest/file_backup
Сразу же скину ссылку на полную информацию о команде. Далее мы рассмотрим основные кейсы.
Копирование каталога
Для копирования каталогов нужно использовать опцию "-r":
$ cp -r source destination
$ ls destination
source
Тут ме переносим весь каталог вместе с его наполнением.
Если нет полной уверенности в том, что каталог "dest" существует, можно добавить флаг "-t" для вывода предупреждения:
$ cp -rt src dest3
cp: cannot stat 'dest3': No such file or directory
Копирование в этом случае выполнено не будет и каталог не будет создан.
Копирование содержимого каталога
Для того, чтобы перенести только содержимое директории, а не ее саму, используем:
$ cp -r src no_dest
$ ls no_dest
file1 file2 file3
Но есть нюансик... Это так работает только, если no_dest ранее не существовал. Если каталог назначения существует, то в нем будет создан src.
Для того чтобы избежать такого поведения можно использовать опцию "-T":
$ cp -rT src yes_dest
ls yes_dest
file1 file2 file3
Как вариант, еще можно решить задачу использованием шаблона поиска:
$ cp src/* dest
Однако в этом случае скрытые файлы скопированы не будут. Ну и это не проблема особо:
$ cp src/* src/.* dest
Обработка существующих файлов
По умолчанию, если файл каталоге назначения уже существует, он будет перезаписан. Если вы хотите, чтобы утилита спросила вас, стоит ли его перезаписывать, используйте флаг "-i":
$ cp -i src/* dest
cp: overwrite 'dest/file1'? y
cp: overwrite 'dest/file2'? y
С помощью опции "-n" можно отключить перезапись существующих ресурсов:
$ cp -n file1 dest
Создание бэкапов
Для существующих файлов можно cделать резервную копию с помощью опции "-b". Если использовать этот флаг, то в конце названия файла резервной копии будет добавлен символ тильды "~":
$ cp -b file1 dest
$ ls dest
file1~
При использовании параметра "--backup" можно настроить имя резервной копии. Вот доступные варианты:
1) none - резервная копия не делается;
2) numbered - к имени файла будет добавляться номер;
3) simple - в конец файла будет добавлен знак "~";
4) existing - если в целевой директории уже есть бэкапы, то будет использоваться аналогичный им тип нейминга;
Чтобы использовать номер в имени бэкапа используйте:
$ cp --backup=numbered file1 dest
$ ls dest
file1.~1~
Ещё один вариант обработки существующих файлов - заменять только, если изначальный новее.
Для этого нужно использовать опцию "-u":
$ cp -u file1 dest
Копирование ссылок
По умолчанию жесткие и символические ссылки копируются как обычные файлы, сохраняя содержимое ресурса, к которому были подвязаны:
$ cp test_link links
$ ls -l links
-rw-rw-r-- 1 ... test_link
Если вы хотите, чтобы символические ссылки копировались, сохраняя свой тип, нужно использовать опцию "-P":
$ cp test_link links
$ ls -l links
lrwxrwxrwx 1 ... test2_link -> test2
Ток, пожалуйста, не забывайте проверять путь к оригиналу на корректность - в примере выше ссылка поломана.
Для жестких ссылок существует другой подход. Если вы хотите, чтобы она осталась собой после копирования, нужно использовать опцию "-l":
$ cp -l hlink hlink1
$ ls -l
-rw-rw-r-- 3 ... file
-rw-rw-r-- 3 ... hlink
-rw-rw-r-- 3 ... hlink1
Сохранение атрибутов
По умолчанию cp обновляет временные метки и атрибуты прав доступа файлов при копировании.
Иногда может возникнуть необходимость их сохранить. Для этого используем "--preserve":
$ cp --preserve=all file dest
LinuxCamp | #utils
👍40🔥18❤6
Как я потрошил iso образ
Был обычный рабочий день: я усердно делил пиццу на равные части. Все шло гладко, как вдруг прилетает тикет с крайне необычным багом - в virtualbox ломается рендер рабочего стола... И это происходит в момент работы с загрузчиком ОС.
Надо что-то делать, т.к. впечатления после такого, скажем, не очень.
Немного помозговав, было принято решение вскрыть ISO образ и подменить несколько бинарников для проверки работоспособности предыдущих версий.
Почему нельзя просто обновить пакеты после установки ОС? Баг воспроизводился в очень специфических условиях, исключительно при первом запуске live образа.
Честно говоря, ранее я не особо вникал в структуру iso-шников и это был первый опыт их пересборки. Сейчас расскажу о нескольких фейлах.
Первое время я пытался подменить deb пакет, т.к. думал, что именно он будет распакован в момент первого запуска. Подменил и как же удивился, когда ничего не поменялось и "dpkg -l" показал изначальную версию))
Оказалось, что пакеты распаковываются, но не сразу, а когда система выполняет финальную "доустановку".
Далее я осмелился посмотреть через "ls -l" расширенные параметры бинарника и увидел, что он не только что поставлен, а был вшит в образ еще на этапе сборки.
И тут я задался вопросом: "Стоп, а как в iso образе представлена файловая система для live пользователя, от которого мы выполняем базовую настройку системы?". В процессе страшного ресерча до меня дошло, что она сжата в:
И если мы "разожмем" ее через:
То увидим внутри что-то очень знакомое:
Именно тут-то и сидели те самые бинари, которые изначально требовалось подменить. Дальше пазл примерно сложился, я обратно собрал всю эту иерархию в ".squashfs":
После упаковал новый iso образ, отладил багу и проработал фикс. На всякий, сразу приложу команду, которой готовил образы:
В общем, вот такой интересный опыт был получен. Как вы, вообще, хотите больше поговорить о файловых системах, внутрянке iso образов, grub?
LinuxCamp | #story
Был обычный рабочий день: я усердно делил пиццу на равные части. Все шло гладко, как вдруг прилетает тикет с крайне необычным багом - в virtualbox ломается рендер рабочего стола... И это происходит в момент работы с загрузчиком ОС.
Надо что-то делать, т.к. впечатления после такого, скажем, не очень.
Немного помозговав, было принято решение вскрыть ISO образ и подменить несколько бинарников для проверки работоспособности предыдущих версий.
Почему нельзя просто обновить пакеты после установки ОС? Баг воспроизводился в очень специфических условиях, исключительно при первом запуске live образа.
Честно говоря, ранее я не особо вникал в структуру iso-шников и это был первый опыт их пересборки. Сейчас расскажу о нескольких фейлах.
Первое время я пытался подменить deb пакет, т.к. думал, что именно он будет распакован в момент первого запуска. Подменил и как же удивился, когда ничего не поменялось и "dpkg -l" показал изначальную версию))
Оказалось, что пакеты распаковываются, но не сразу, а когда система выполняет финальную "доустановку".
Далее я осмелился посмотреть через "ls -l" расширенные параметры бинарника и увидел, что он не только что поставлен, а был вшит в образ еще на этапе сборки.
И тут я задался вопросом: "Стоп, а как в iso образе представлена файловая система для live пользователя, от которого мы выполняем базовую настройку системы?". В процессе страшного ресерча до меня дошло, что она сжата в:
./live/filesystem.squashfs
И если мы "разожмем" ее через:
$ unsquashfs filesystem.squashfs
То увидим внутри что-то очень знакомое:
bin etc initrd.img lib media opt
...
Именно тут-то и сидели те самые бинари, которые изначально требовалось подменить. Дальше пазл примерно сложился, я обратно собрал всю эту иерархию в ".squashfs":
$ mksquashfs squashfs-root filesystem.squashfs
После упаковал новый iso образ, отладил багу и проработал фикс. На всякий, сразу приложу команду, которой готовил образы:
$ sudo mkisofs -o ~/Загрузки/new.iso -quiet -R -b boot/grub/bios.img -no-emul-boot -boot-load-size 4 -boot-info-table ./
В общем, вот такой интересный опыт был получен. Как вы, вообще, хотите больше поговорить о файловых системах, внутрянке iso образов, grub?
LinuxCamp | #story
👍84🔥26🥰5❤🔥3❤2🤔2
Топ ресурсов по изучению Linux
Сегодня выдам персональный список ресурсов (книги, видео), по которым можно на вполне достойном уровне освоить Linux. Через все приведенные источники информации я сам прошел, поэтому далее только годнота)
YouTube:
1) NetworkChuck. Ничего сверх глубокого тут не найдешь, но самые основы можно проработать. Мне тут не столько материал понравился, сколько подача. Если вы ранее вообще не имели дело с Linux и хотели бы начать, можно рассмотреть 2 плейлиста: Linux for Hackers, Bash.
У автора имеется платный курс, но за него ручаться не могу, т.к. сам не проходил.
Помню, впервые заинтересовался Linux с его видосов и потом начал идти вглубь по сторонним ресурсам.
2) Linux TV. Это уже артиллерия посерьезнее. В обучающих видео автора раскрывается материал для уровней junior-middle+. Козырь канала - плейлист "Linux Crash Course" на 79 видео. Также в арсенале плейлисты: Bash Scripting, Vim Beginners Guide и Linux Commands for Beginners.
3) DistroTube. На канале не все видео обучающие - контент разноплановый, но в контексте Linux. Из чего-то образовательного могу порекомендовать плейлист "The Command Line" - автор рассказывает про различные утилиты командной строки и довольно подробно их разбирает.
Книги:
1) Linux. Командная строка. Лучшие практики (Дэниел Барретт). Относительно конкурентов, книга небольшая (257 стр.).
Отлично подойдет, если вы хотите с минимум воды освоить оболочку и получить необходимый минимум для комфортной работы в ней.
Для того, чтобы разобраться в bash и начать эффективно работать в cmd, я бы рекомендовал начать именно с нее.
2) Командная строка Linux (Уильям Шоттс). Книга - отличное дополнение к п.1. Ее можно прочесть сразу после предыдущей, чтобы поглубже разобраться в теме.
Тут затрагивается больше команд, cmd утилит, конструкций оболочки и базовых концепций: сигналы, процессы и т.д.
Начинать с нее я бы не стал, т.к. много лишней информации, без которой по началу можно спокойно обойтись.
3) Linux API исчерпывающее руководство (Майкл Керриск). Это - база. С нее начался мой путь в мир прикладной разработки под Linux.
Вполне могу рекомендовать первой к прочтению, особенно, если вы разраб и пишете на C/C++.
Вы познакомитесь с различными подсистемами ОС, протоколами передачи данных, системными вызовами и много с чем еще.
4) Внутреннее устройство Linux (Брайан Уорд). Хорошо читается после Linux API, дополняет материал и затрагивает важные аспекты, которые не рассматриваются в п.3.
LinuxCamp | #top
Сегодня выдам персональный список ресурсов (книги, видео), по которым можно на вполне достойном уровне освоить Linux. Через все приведенные источники информации я сам прошел, поэтому далее только годнота)
YouTube:
1) NetworkChuck. Ничего сверх глубокого тут не найдешь, но самые основы можно проработать. Мне тут не столько материал понравился, сколько подача. Если вы ранее вообще не имели дело с Linux и хотели бы начать, можно рассмотреть 2 плейлиста: Linux for Hackers, Bash.
У автора имеется платный курс, но за него ручаться не могу, т.к. сам не проходил.
Помню, впервые заинтересовался Linux с его видосов и потом начал идти вглубь по сторонним ресурсам.
2) Linux TV. Это уже артиллерия посерьезнее. В обучающих видео автора раскрывается материал для уровней junior-middle+. Козырь канала - плейлист "Linux Crash Course" на 79 видео. Также в арсенале плейлисты: Bash Scripting, Vim Beginners Guide и Linux Commands for Beginners.
3) DistroTube. На канале не все видео обучающие - контент разноплановый, но в контексте Linux. Из чего-то образовательного могу порекомендовать плейлист "The Command Line" - автор рассказывает про различные утилиты командной строки и довольно подробно их разбирает.
Книги:
1) Linux. Командная строка. Лучшие практики (Дэниел Барретт). Относительно конкурентов, книга небольшая (257 стр.).
Отлично подойдет, если вы хотите с минимум воды освоить оболочку и получить необходимый минимум для комфортной работы в ней.
Для того, чтобы разобраться в bash и начать эффективно работать в cmd, я бы рекомендовал начать именно с нее.
2) Командная строка Linux (Уильям Шоттс). Книга - отличное дополнение к п.1. Ее можно прочесть сразу после предыдущей, чтобы поглубже разобраться в теме.
Тут затрагивается больше команд, cmd утилит, конструкций оболочки и базовых концепций: сигналы, процессы и т.д.
Начинать с нее я бы не стал, т.к. много лишней информации, без которой по началу можно спокойно обойтись.
3) Linux API исчерпывающее руководство (Майкл Керриск). Это - база. С нее начался мой путь в мир прикладной разработки под Linux.
Вполне могу рекомендовать первой к прочтению, особенно, если вы разраб и пишете на C/C++.
Вы познакомитесь с различными подсистемами ОС, протоколами передачи данных, системными вызовами и много с чем еще.
4) Внутреннее устройство Linux (Брайан Уорд). Хорошо читается после Linux API, дополняет материал и затрагивает важные аспекты, которые не рассматриваются в п.3.
LinuxCamp | #top
👍52🔥9❤🔥5
Настройка прав по умолчанию
Каждому файлу или каталогу присваивается ряд дефолтных прав, которые определяют кто и как может им распоряжаться:
Команда umask (встроена в оболочку) позволяет настроить те самые права, которые будут применимы по умолчанию к ресурсам при их создании.
Ранее мы затрагивали права в:
1) разница между chmod и chown;
2) файл групп /etc/group;
3) шпаргалка по правам доступа;
Немного вспомним наши права
В общем случае права доступа в UNIX разбиты на три категории: u (user), g (group), o (other).
Каждая категория имеет три типа битов, которые различны для файлов и каталогов.
Для файлов:
r (read, 4, 100) – чтение файла.
w (write, 2, 010) – изменение файла.
x (execute, 1, 001) – выполнение файла как программы.
Для каталогов:
r (read, 4, 100) – чтение списка файлов.
w (write, 2, 010) – изменение и создание файлов в каталоге.
x (execute, 1, 001) – открытие файлов в каталоге.
Когда создаётся новый ресурс, система назначает ему максимально возможные права: файлы (666 = rw-rw-rw-), каталоги (777 = rwxrwxrwx).
Как работает umask
Суть работы команды - не добавить права, а ограничивает их, убрав заданные биты доступа.
Итоговый набор бит рассчитывается довольно просто: от максимальных прав отнимается маска.
Дефолтное значение маски обычно следующее:
Поэтому права по умолчанию для файла будут:
А для каталога:
Важное замечание: с помощью маски не получится сохранить либо исключить бит выполнения "x" для файлов. Этот флаг можно обработать только для каталогов:
Напомню, что права файла рассчитываются на основе адского набора "666", где выполнение уже отключено.
Формы синтаксиса umask
У команды довольно простой синтаксис и несколько способов определения маски:
Посмотреть текущее значение маски можно двумя способами:
Способы задания маски
Вообще, маска может определяться 4 цифрами, но первую можно опустить, т.к. она не используется:
Команда umask работает с цифрами справа налево, поэтому незначащие нули можно тоже опустить, по необходимости:
Маску можно задать и с помощью более традиционных обозначений:
В таком формате оно, как пишется, так и понимается - работает по принципу chmod.
Мы не исключаем "rwx" для пользователя и группы, а чистим все права для "остальных" персон. Такая запись равна маске "007":
Группы прав также можно объединять:
Или же задавать сразу для всех категорий, использовав "a" (all):
Также можно работать с отдельными правами. Оператором "+" или "-" можно разрешить или запретить целевое действие:
Можно и комбинировать два предыдущих способа. Например, разрешить пользователю все операции, а группе и остальным убрать право на чтение:
LinuxCamp | #utils
Каждому файлу или каталогу присваивается ряд дефолтных прав, которые определяют кто и как может им распоряжаться:
$ ls -l
-rw-r--r-- ... dhcpcd.conf
Команда umask (встроена в оболочку) позволяет настроить те самые права, которые будут применимы по умолчанию к ресурсам при их создании.
Ранее мы затрагивали права в:
1) разница между chmod и chown;
2) файл групп /etc/group;
3) шпаргалка по правам доступа;
Немного вспомним наши права
В общем случае права доступа в UNIX разбиты на три категории: u (user), g (group), o (other).
Каждая категория имеет три типа битов, которые различны для файлов и каталогов.
Для файлов:
r (read, 4, 100) – чтение файла.
w (write, 2, 010) – изменение файла.
x (execute, 1, 001) – выполнение файла как программы.
Для каталогов:
r (read, 4, 100) – чтение списка файлов.
w (write, 2, 010) – изменение и создание файлов в каталоге.
x (execute, 1, 001) – открытие файлов в каталоге.
Когда создаётся новый ресурс, система назначает ему максимально возможные права: файлы (666 = rw-rw-rw-), каталоги (777 = rwxrwxrwx).
Как работает umask
Суть работы команды - не добавить права, а ограничивает их, убрав заданные биты доступа.
Итоговый набор бит рассчитывается довольно просто: от максимальных прав отнимается маска.
Дефолтное значение маски обычно следующее:
$ umask
0002
Поэтому права по умолчанию для файла будут:
666 - 002 = 664
-rw-rw-r--
А для каталога:
777 - 002 = 775
drwxrwxr-x
Важное замечание: с помощью маски не получится сохранить либо исключить бит выполнения "x" для файлов. Этот флаг можно обработать только для каталогов:
$ umask 010
$ mkdir newdir
$ ls -l
drwxrw-rwx ... newdir
Напомню, что права файла рассчитываются на основе адского набора "666", где выполнение уже отключено.
Формы синтаксиса umask
У команды довольно простой синтаксис и несколько способов определения маски:
$ umask опции восьмеричная_маска
$ umask опции u=права,g=права,o=права
Посмотреть текущее значение маски можно двумя способами:
$ umask
0002
$ umask -S
u=rwx,g=rwx,o=rx
Способы задания маски
Вообще, маска может определяться 4 цифрами, но первую можно опустить, т.к. она не используется:
$ umask 002
$ umask
0002
Команда umask работает с цифрами справа налево, поэтому незначащие нули можно тоже опустить, по необходимости:
$ umask 77
$ umask
0077
Маску можно задать и с помощью более традиционных обозначений:
$ umask u=rwx,g=rwx,o=
В таком формате оно, как пишется, так и понимается - работает по принципу chmod.
Мы не исключаем "rwx" для пользователя и группы, а чистим все права для "остальных" персон. Такая запись равна маске "007":
$ umask
0007
$ touch filetest
$ ls -l
-rw-rw---- ... filetest
Группы прав также можно объединять:
$ umask ug=rwx,o=rx
Или же задавать сразу для всех категорий, использовав "a" (all):
$ umask a=rwx
Также можно работать с отдельными правами. Оператором "+" или "-" можно разрешить или запретить целевое действие:
$ umask -S ug-w
u=rx,g=rx,o=rx
$ umask -S a+w
u=rwx,g=rwx,o=rwx
Можно и комбинировать два предыдущих способа. Например, разрешить пользователю все операции, а группе и остальным убрать право на чтение:
$ umask u=rwx,go-r
LinuxCamp | #utils
👍26🔥11❤🔥7👎1
Как получить доступ к данным iso образа?
Когда я решал проблему с переделкой iso образа - первой ступенью была задача понять то, как можно получить доступ к его внутрянке. Тыкался-мыкался и что-то, вроде, понял) Об этом и поговорим.
Так, а чем по своей сути вообще является iso файл? Грубо говоря, это несжатый архив с точной копией данных блочного устройства (hdd, ssd, cd) в формате файловой системы ISO9660:
В зависимости от содержимого образ может быть загрузочным и не загрузочным. Давайте из приведенного выше описания iso-шника выведем возможные способы работы с ним:
1) он представляет собой архив - его можно распаковать;
2) он содержит файловую систему ISO9660 - его можно монтировать;
Начнем с "распакоуки". Для этого можем воспользоваться утилитой 7z:
После завершения процесса мы вольны вносить в файловую структуру свои коррективы. После правок нужно будет заново собрать установочный iso образ. Для этого есть утилитка mkisofs, которая корректно собирает ISO9660 архивы из файлов и каталогов.
Второй способ - монтировать образ и скопировать его содержимое.
В привычном для нас понимании, монтирование относится к блочным устройствам (usb, ssd, hdd), которые содержат определенную файловую систему (exFAT, ext, zfs). Такой механизм позволяет нам получить доступ к содержимому носителей.
Но вот в чем дело, iso файл не является блочным устройством и его нельзя просто так примонтировать... Ничего, есть решение - механизм loop device.
Loop device — это виртуальное блочное устройство, которое позволяет использовать обычный ресурс с файловой системой, как физический девайс. Через него можно смонтировать образ и получить доступ к его файловой системе.
Посмотреть то, какое устройство с каким ресурсом соотносится, можно через команду losetup:
Для того, чтобы создать и монтировать "loop device", используем mount:
Теперь, т.к. файловая система ISO9660 является "read-only", нам нужно скопировать все содержимое образа в отдельный каталог:
Далее "по уму" редактируем образ и пересобираем его с помощью mkisofs:
Если все сделано правильно, на выходе мы получим "bootable" образ.
LinuxCamp | #filesystem
Когда я решал проблему с переделкой iso образа - первой ступенью была задача понять то, как можно получить доступ к его внутрянке. Тыкался-мыкался и что-то, вроде, понял) Об этом и поговорим.
Так, а чем по своей сути вообще является iso файл? Грубо говоря, это несжатый архив с точной копией данных блочного устройства (hdd, ssd, cd) в формате файловой системы ISO9660:
$ file linuxmint-22.1-xfce-64bit.iso
linuxmint-22.1-xfce-64bit.iso: ISO 9660 CD-ROM filesystem data (DOS/MBR boot sector) ... (bootable)
В зависимости от содержимого образ может быть загрузочным и не загрузочным. Давайте из приведенного выше описания iso-шника выведем возможные способы работы с ним:
1) он представляет собой архив - его можно распаковать;
2) он содержит файловую систему ISO9660 - его можно монтировать;
Начнем с "распакоуки". Для этого можем воспользоваться утилитой 7z:
$ sudo apt install p7zip-full
$ 7z x linux*.iso -o./extract
После завершения процесса мы вольны вносить в файловую структуру свои коррективы. После правок нужно будет заново собрать установочный iso образ. Для этого есть утилитка mkisofs, которая корректно собирает ISO9660 архивы из файлов и каталогов.
Второй способ - монтировать образ и скопировать его содержимое.
В привычном для нас понимании, монтирование относится к блочным устройствам (usb, ssd, hdd), которые содержат определенную файловую систему (exFAT, ext, zfs). Такой механизм позволяет нам получить доступ к содержимому носителей.
Но вот в чем дело, iso файл не является блочным устройством и его нельзя просто так примонтировать... Ничего, есть решение - механизм loop device.
Loop device — это виртуальное блочное устройство, которое позволяет использовать обычный ресурс с файловой системой, как физический девайс. Через него можно смонтировать образ и получить доступ к его файловой системе.
Посмотреть то, какое устройство с каким ресурсом соотносится, можно через команду losetup:
$ sudo losetup -a
/dev/loop13: [64512]:2672215 (/path/to/output.iso)
Для того, чтобы создать и монтировать "loop device", используем mount:
$ sudo mount -o loop test.iso ./mnt_point
Теперь, т.к. файловая система ISO9660 является "read-only", нам нужно скопировать все содержимое образа в отдельный каталог:
$ mkdir new_mnt_point
$ cp -rT mnt_point new_mnt_point
Далее "по уму" редактируем образ и пересобираем его с помощью mkisofs:
$ sudo mkisofs -o ./new.iso -quiet -R -b boot/grub/bios.img -no-emul-boot -boot-load-size 4 -boot-info-table ./new_mnt_point
Если все сделано правильно, на выходе мы получим "bootable" образ.
LinuxCamp | #filesystem
🔥46👍25👏5❤1
Прокачиваемся в tr
Сегодня у нас на разборе одна из культовых утилит "tr". Используется она для форматирования текста: удаления и замены символов.
Чаще всего можно встретить в паре со сторонними командами, которые выводят в stdout текстовый поток: cat, head, echo и т.д.
Команда имеет следующий вид:
Сетами представлены наборы символов, с которыми tr будет работать. Второй набор не всегда используется.
Команда разбирает текст посимвольно и выполняет операцию для каждого элемента отдельно.
Флаги команды tr:
1) -d (--delete): удаляет элементы из первого набора:
2) -c (--complement): обработать каждый символ, который не входит в набор "SET1":
В примере мы удалили все символы, которые не входят в перечисление 'a-zA-Z\n';
Таким же макаром можно все буквы удалить и оставить только цифры:
3) -s (--squeeze-repeats): cжимает повторяющиеся символы из первого набора до одного:
4) -t (--truncate-set1): обрезает первый набор до длины второго:
Если длина первого набора больше и мы не указываем флаг, каждый последующий его символ, который (по номеру > конец "SET2"), будет заменен:
При своем дефолтном поведении, программа заменяет символы из "SET1" на элементы "SET2":
Команда умеет парсить шаблоны: [:upper:], [:lower:] и т.д. Детальнее можно ознакомиться в мануале:
Данные на вход можно получить и через файлик. Для этого мы используем перенаправление:
Измененные данные нужно куда-то записать? Правильно, перенаправляем вывод:
LinuxCamp | #utils
Сегодня у нас на разборе одна из культовых утилит "tr". Используется она для форматирования текста: удаления и замены символов.
Чаще всего можно встретить в паре со сторонними командами, которые выводят в stdout текстовый поток: cat, head, echo и т.д.
Команда имеет следующий вид:
$ tr флаг SET1 [SET2]
Сетами представлены наборы символов, с которыми tr будет работать. Второй набор не всегда используется.
Команда разбирает текст посимвольно и выполняет операцию для каждого элемента отдельно.
Флаги команды tr:
1) -d (--delete): удаляет элементы из первого набора:
$ echo "Hello 123 world" | tr -d ' a-zA-Z'
123
2) -c (--complement): обработать каждый символ, который не входит в набор "SET1":
$ echo "Hello 123 world" | tr -cd 'a-zA-Z\n'
Helloworld
В примере мы удалили все символы, которые не входят в перечисление 'a-zA-Z\n';
Таким же макаром можно все буквы удалить и оставить только цифры:
$ cat customer.csv
USA,1234567890
Canada,0987654321
$ cat customer.csv | tr -cd '0-9\n'
1234567890
0987654321
3) -s (--squeeze-repeats): cжимает повторяющиеся символы из первого набора до одного:
$ echo "Hello World" | tr -s ' '
Hello World
4) -t (--truncate-set1): обрезает первый набор до длины второго:
$ echo "abcdef" | tr -t 'abcdef' '123'
123def
Если длина первого набора больше и мы не указываем флаг, каждый последующий его символ, который (по номеру > конец "SET2"), будет заменен:
$ echo "abcdef" | tr 'abcdef' '123'
123333
При своем дефолтном поведении, программа заменяет символы из "SET1" на элементы "SET2":
$ echo "Hello World" | tr 'a-z' 'A-Z'
HELLO WORLD
Команда умеет парсить шаблоны: [:upper:], [:lower:] и т.д. Детальнее можно ознакомиться в мануале:
$ echo "hello world" | tr [:lower:] [:upper:]
HELLO WORLD
Данные на вход можно получить и через файлик. Для этого мы используем перенаправление:
$ cat infile
www.baeldung.com
$ tr 'a-z' 'A-Z' < infile
WWW.BAELDUNG.COM
Измененные данные нужно куда-то записать? Правильно, перенаправляем вывод:
$ tr 'a-z' 'A-Z' < infile > outfile
LinuxCamp | #utils
🔥40👍29❤🔥5❤4🎉1🌭1
Инъекция пользы
Если хотим передать файлы или каталоги с локальной системы на удаленный ssh сервер или наоборот, используем команды: scp и sftp.
Скопируем файл с удаленного хоста в локальный каталог:
Скопируем файлы с локального компьютера на удаленный хост:
Скопируем файл с одного удаленного хоста на другой:
Прога sftp не требует постоянно указывать адрес ssh сервера. Вместо этого мы подключаемся к нему один раз и используем интерфейс get и put:
Для передачи каталогов используем флаг "-r":
Также хочется отметить, что sftp имеет важное преимущество перед обычным ftp — она не требует, чтобы на удаленном узле работал сервер FTP. Ей необходим только SSH.
LinuxCamp | #microhelp
Если хотим передать файлы или каталоги с локальной системы на удаленный ssh сервер или наоборот, используем команды: scp и sftp.
Скопируем файл с удаленного хоста в локальный каталог:
$ scp user@host:/path/to/file /local/dir
Скопируем файлы с локального компьютера на удаленный хост:
$ scp /local/dir/file user@host:/remote/dir
Скопируем файл с одного удаленного хоста на другой:
$ scp user1@host1:/remote/file user2@host2:/remote/dir
Прога sftp не требует постоянно указывать адрес ssh сервера. Вместо этого мы подключаемся к нему один раз и используем интерфейс get и put:
$ sftp user@host
sftp> get /remote/dir/file /local/dir
sftp> put /local/dir/file /remote/dir
Для передачи каталогов используем флаг "-r":
$ scp -r /local/dir user@host:/remote/dir
$ sftp> put -r /local/dir /remote/dir
Также хочется отметить, что sftp имеет важное преимущество перед обычным ftp — она не требует, чтобы на удаленном узле работал сервер FTP. Ей необходим только SSH.
LinuxCamp | #microhelp
👍33🔥28❤🔥4❤1😁1
Итоги квартала
По традиции набросал сводку ключевых постов (декабрь - февраль 2025):
Сигналы
1. Отправка сигналов: kill()
2. Отправка сигнала самому себе: raise()
3. Защита от незваных гостей: сигнальная маска
4. Работа с ожидающими сигналами
5. Перехватывай сигналы, как профи: sigaction()
6. Функции для работы с набором сигналов
Потоки ввода-вывода
1. Потоки ввода-вывода: stdout, stderr, stdin
2. Операторы перенаправления ввода-вывода: >, >>
3. Операторы перенаправления ввода-вывода: <, <<
4. Операторы перенаправления ввода-вывода: |
Оболочка
1. Шаблоны командной оболочки: *, ?, []
2. Вычисление переменных в оболочке
3. Условные списки: ||, &&
4. Подстановка вывода команды: $()
5. Передача команды в качестве bash аргумента
6. Выполнение команды в подоболочке: ()
7. Расширение команд с помощью {}
Задания
1. Фоновое выполнение команд и задания
2. Команды управления заданиями: fg, bg, jobs
3. Проблема с вводом-выводом в фоновом выполнении
Разбор команд
1. Автоматизация задач с xargs
2. Xargs и флаги: -L, -t
3. Практика использования xargs
4. Управление буфером обмена: xclip
5. Прокачиваемся в grep
6. Просмотр файлов: head и tail
7. Прокачиваемся в find
8. Прокачиваемся в cp
9. Настройка прав по умолчанию: umask
10. Прокачиваемся в tr
Базовый linux:
1. Раскрываем завесу тайн над устройствами
2. Что такое /dev/null и почему туда направляют данные?
Личные практики:
1. Не самый стандартный способ использовать syslog
2. Как я потрошил iso образ
3. Как получить доступ к данным iso образа?
Рекомендации
1. Топ ресурсов по изучению Linux
LinuxCamp | #sumup
По традиции набросал сводку ключевых постов (декабрь - февраль 2025):
Сигналы
1. Отправка сигналов: kill()
2. Отправка сигнала самому себе: raise()
3. Защита от незваных гостей: сигнальная маска
4. Работа с ожидающими сигналами
5. Перехватывай сигналы, как профи: sigaction()
6. Функции для работы с набором сигналов
Потоки ввода-вывода
1. Потоки ввода-вывода: stdout, stderr, stdin
2. Операторы перенаправления ввода-вывода: >, >>
3. Операторы перенаправления ввода-вывода: <, <<
4. Операторы перенаправления ввода-вывода: |
Оболочка
1. Шаблоны командной оболочки: *, ?, []
2. Вычисление переменных в оболочке
3. Условные списки: ||, &&
4. Подстановка вывода команды: $()
5. Передача команды в качестве bash аргумента
6. Выполнение команды в подоболочке: ()
7. Расширение команд с помощью {}
Задания
1. Фоновое выполнение команд и задания
2. Команды управления заданиями: fg, bg, jobs
3. Проблема с вводом-выводом в фоновом выполнении
Разбор команд
1. Автоматизация задач с xargs
2. Xargs и флаги: -L, -t
3. Практика использования xargs
4. Управление буфером обмена: xclip
5. Прокачиваемся в grep
6. Просмотр файлов: head и tail
7. Прокачиваемся в find
8. Прокачиваемся в cp
9. Настройка прав по умолчанию: umask
10. Прокачиваемся в tr
Базовый linux:
1. Раскрываем завесу тайн над устройствами
2. Что такое /dev/null и почему туда направляют данные?
Личные практики:
1. Не самый стандартный способ использовать syslog
2. Как я потрошил iso образ
3. Как получить доступ к данным iso образа?
Рекомендации
1. Топ ресурсов по изучению Linux
LinuxCamp | #sumup
1🔥57👍24❤🔥4❤2
Перемещайся по файловой системе как флеш: CDPATH
Многие из вас умеют быстро ходить по файловой системе через автодополнение пути по TAB, использование '~' для указания домашнего каталога или команде "cd -", которая позволяет переключаться между текущим и прежним каталогами:
Но этого мало для того, чтобы считать себя профи. Предположим, у вас есть важный каталог "/home/smith/Family/Memories/Photos", который вы часто посещаете.
Скорее всего, чтобы попасть в него, вы введете путь:
Да, но было бы круто сократить этот путь до Photos, независимо от того, где мы находимся:
Если вы не сидите где-то, где есть подкаталог Photos, то получите ошибочку:
Можно сделать так, чтобы команда cd проверяла дополнительные пути помимо текущего каталога. Для этого нужно перечислить их в переменной CDPATH:
Несколько каталогов можно указать через разделитель:
Итого: определяем переменную либо в локальном "~/.bashrc" либо в глобальном "/etc/profile" и перечисляем в ней самые популярные каталоги поиска.
Для меня это, допустим, каталог "Sources", в котором лежат исходники различных утилит:
Если нужно быстро переключиться на другой проект, я не буду вводить полный путь до него и укажу только название.
LinuxCamp | #utils
Многие из вас умеют быстро ходить по файловой системе через автодополнение пути по TAB, использование '~' для указания домашнего каталога или команде "cd -", которая позволяет переключаться между текущим и прежним каталогами:
$ cd -
/home/xoadmin/Documents
$ cd -
/home/xoadmin/Music
Но этого мало для того, чтобы считать себя профи. Предположим, у вас есть важный каталог "/home/smith/Family/Memories/Photos", который вы часто посещаете.
Скорее всего, чтобы попасть в него, вы введете путь:
$ cd ~/Family/Memories/Photos
Да, но было бы круто сократить этот путь до Photos, независимо от того, где мы находимся:
$ cd Photos
Если вы не сидите где-то, где есть подкаталог Photos, то получите ошибочку:
bash: cd: Photos: No such file or directory
Можно сделать так, чтобы команда cd проверяла дополнительные пути помимо текущего каталога. Для этого нужно перечислить их в переменной CDPATH:
$ CDPATH=$HOME/Family/Memories
$ pwd
/etc
$ cd Photos
/home/smith/Family/Memories/Photos
Несколько каталогов можно указать через разделитель:
$ CDPATH=$HOME:$HOME/Projects:$HOME/Family/Memories:/usr/local
Итого: определяем переменную либо в локальном "~/.bashrc" либо в глобальном "/etc/profile" и перечисляем в ней самые популярные каталоги поиска.
Для меня это, допустим, каталог "Sources", в котором лежат исходники различных утилит:
$ echo $CDPATH
/home/xoadmin/Sources
$ pwd
/home/xoadmin/Music
$ cd picom
/home/xoadmin/Sources/picom
Если нужно быстро переключиться на другой проект, я не буду вводить полный путь до него и укажу только название.
LinuxCamp | #utils
🔥47👍32❤12
Разница между su и su -
Ни для кого не секрет, что Linux - система, с которой можно работать от разных пользователей. Сегодня я запускаю сессию от Паши, завтра от Пети.
Когда вы в сессии открываете терминал, стартует оболочка, которая подстраивает окружение под конкретного юзера: выполняет скрипты, определяет переменные.
Бывает, приходится, работая в сессии одного пользователя, переключиться на другого, например, чтобы использовать ресурсы, ограниченные правами доступа. Для этого мы используем команду "su" (substitute user), которая позволяет сменить пользователя в текущей оболочке:
После того, как мы выполним команду, создастся дочерняя оболочка, которая переймет все переменные окружения родителя, определит пользовательские (USER, HOME ...) и выполнит локальные "Васины" скрипты: /home/vasya/.bashrc и т.д.:
Чет какая-то каша выходит. Половина Васиных переменных, половина юзера xoadmin. Такой способ полезен, когда нам нужно быстро поменять пользователя и не требуется его окружение в изначальном виде.
Если нужно полностью воссоздать среду, как при чистом входе в систему, следует использовать "su -":
Окружение родителя мы не наследуем и запускаем оболочку типа "login shell", которая выполнит дополнительные скрипты инициализации "/etc/profile", "~/.bash_profile". Подробнее про типы оболочек говорили вот тут, а про этапы их инициализации тут.
Также, когда мы используем "su -", наш рабочий каталог переключается на домашний для целевого пользователя. Мелочь, но факт:
LinuxCamp | #shell
Ни для кого не секрет, что Linux - система, с которой можно работать от разных пользователей. Сегодня я запускаю сессию от Паши, завтра от Пети.
Когда вы в сессии открываете терминал, стартует оболочка, которая подстраивает окружение под конкретного юзера: выполняет скрипты, определяет переменные.
Бывает, приходится, работая в сессии одного пользователя, переключиться на другого, например, чтобы использовать ресурсы, ограниченные правами доступа. Для этого мы используем команду "su" (substitute user), которая позволяет сменить пользователя в текущей оболочке:
$ su vasya
После того, как мы выполним команду, создастся дочерняя оболочка, которая переймет все переменные окружения родителя, определит пользовательские (USER, HOME ...) и выполнит локальные "Васины" скрипты: /home/vasya/.bashrc и т.д.:
$ export USER1VAR="vasya"
$ su xoadmin
$ printenv | grep USER
USER=xoadmin
USER1VAR=vasya
Чет какая-то каша выходит. Половина Васиных переменных, половина юзера xoadmin. Такой способ полезен, когда нам нужно быстро поменять пользователя и не требуется его окружение в изначальном виде.
Если нужно полностью воссоздать среду, как при чистом входе в систему, следует использовать "su -":
$ su - xoadmin
Окружение родителя мы не наследуем и запускаем оболочку типа "login shell", которая выполнит дополнительные скрипты инициализации "/etc/profile", "~/.bash_profile". Подробнее про типы оболочек говорили вот тут, а про этапы их инициализации тут.
Также, когда мы используем "su -", наш рабочий каталог переключается на домашний для целевого пользователя. Мелочь, но факт:
$ pwd
/home/vasya/Music
$ su - xoadmin
$ pwd
/home/xoadmin
LinuxCamp | #shell
👍78🔥15❤🔥8❤5
Стрелка за 200 в работе с файловой системой
Представим такой рабочий процесс, когда нам нужно перемещаться между 4 каталогами, расположенными по совершенно разным путям.
Использовать "cd -" не вариант, т.к. оболочка запоминает только 1 прошлый каталог. Можно использовать CDPATH, но тогда нужно запоминать названия директорий, с которыми работаем.
Команды оболочки pushd, popd и dirs позволяют обойти это ограничение. Предположим, вы создаете локальный сайт и работаете с ресурсами:
Быстро переключаться между ними можно с помощью функции оболочки - "стеком каталогов".
Стек каталогов — это список директорий, которые вы посетили и решили отслеживать в текущем экземпляре оболочки. Изначально он содержит только текущий путь.
Просмотреть стек можно, используя команду dirs:
Вывод команды можно напечатать столбцом "-p":
А можно и пронумеровать "-v". Это нам позволит вдальнейшем удобнее переключаться между каталогами:
Вы управляете стеком, выполняя две операции: pushing и popping (есть, кста, такой стиль танца - весело выглядит).
Pushing каталога добавляет его в начало списка (вершину стека) и переходит в него:
Для того, чтобы только добавить каталог в стек и не переходить на него, нужно использовать флаг "-n".
Popping удаляет верхний каталог из стека и возвращает нас на следующий за ним:
Если хотим полностью очистить стек, тогда либо выполняем "dirs -c", либо зовем popd до тех пор, пока не увидим:
Принцип работы со стеком заключается в том, что мы добавляем туда каталоги, после чего прыгаем по ним, используя аргументы для pushd и popd, которые рассмотрим далее.
LinuxCamp | #shell
Представим такой рабочий процесс, когда нам нужно перемещаться между 4 каталогами, расположенными по совершенно разным путям.
Использовать "cd -" не вариант, т.к. оболочка запоминает только 1 прошлый каталог. Можно использовать CDPATH, но тогда нужно запоминать названия директорий, с которыми работаем.
Команды оболочки pushd, popd и dirs позволяют обойти это ограничение. Предположим, вы создаете локальный сайт и работаете с ресурсами:
/var/www/html
/etc/apache2
/etc/ssl/certs
~/Web/src
Быстро переключаться между ними можно с помощью функции оболочки - "стеком каталогов".
Стек каталогов — это список директорий, которые вы посетили и решили отслеживать в текущем экземпляре оболочки. Изначально он содержит только текущий путь.
Просмотреть стек можно, используя команду dirs:
$ dirs
/etc/ssl/certs /etc/apache2 /var/www/html ~/Web/src
Вывод команды можно напечатать столбцом "-p":
$ dirs -p
/etc/ssl/certs
/etc/apache2
...
А можно и пронумеровать "-v". Это нам позволит вдальнейшем удобнее переключаться между каталогами:
$ dirs -v
0 /etc/ssl/certs
1 /etc/apache2
...
Вы управляете стеком, выполняя две операции: pushing и popping (есть, кста, такой стиль танца - весело выглядит).
Pushing каталога добавляет его в начало списка (вершину стека) и переходит в него:
$ pushd /etc/apache2
/etc/apache2 /var/www/html
Для того, чтобы только добавить каталог в стек и не переходить на него, нужно использовать флаг "-n".
Popping удаляет верхний каталог из стека и возвращает нас на следующий за ним:
$ popd
/var/www/html
Если хотим полностью очистить стек, тогда либо выполняем "dirs -c", либо зовем popd до тех пор, пока не увидим:
$ popd
bash: popd: directory stack empty
Принцип работы со стеком заключается в том, что мы добавляем туда каталоги, после чего прыгаем по ним, используя аргументы для pushd и popd, которые рассмотрим далее.
LinuxCamp | #shell
👍39🔥17❤🔥3👎1