LinuxCamp | DevOps – Telegram
LinuxCamp | DevOps
14.2K subscribers
194 photos
7 videos
300 links
Обо мне: C/C++/Linux эксперт. Говорим про разработку, Linux, DevOps, сети и администрирование.

Админ (реклама): @XoDefender
Чат: @linuxcamp_chat

Менеджер: @Spiral_Yuri
Биржа: https://telega.in/c/linuxcamp_tg

№ 6327102672
Download Telegram
Явные подоболочки

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

С дочерними оболочками так не работает - тот же алиас мы должны определить в конфиге, иначе она его не сможет использовать.

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

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

Для этого просто заключим команду в круглые скобки:


$ (cd /usr/local && ls)
bin etc games lib man sbin share

$ pwd
/home/smith


Как видим, первая команда выполнилась в подоболочке и не поменяла текущую рабочую директорию => нам не нужно повторно вызывать cd.

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

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

1) изи - использовать флаг "" c указанием путь:


$ tar -xzf package.tar.gz -C ./extr


2) хардкор - передать tar-данные в подоболочку, которая зайдет в нужный каталог и выполнит архивирование из стандартного вывода (STDOUT):


cat package.tar.gz | (cd ./extr && tar xzvf -)


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


$ dpkg-buildpackage -b -us -uc && (cd ..; ls -l)


Раньше приходилось держать доп. терминал, по сути, для 1 примитивной задачи)

LinuxCamp
👍28🔥16❤‍🔥3
Запускаем чат LinuxCamp

Нас уже немало набежало и пришло время укреплять комьюнити)

Чат - место, где мы будем вести оживленное общение, помогать друг другу решать задачи по администрированию/разработке, отвечать на вопросы и делиться интересными новостями.

Если вы хотите окружить себя единомышленниками, перенимать опыт и делиться им, welcome в LinuxCamp | Chat.
👍17❤‍🔥134👎1
1000 & 1 способ: задача

Данная рубрика отражает возможность в Linux выполнить одну и ту же задачу "1000 & 1" изощренным способом.

Суть следующая: я даю задачку на подумать, вы пишите свои варианты решения в комменты, после чего я демонстрирую и объясняю способ, с которым сам работал.

Задача: наиболее интересно, используя команду/команды Bash, создать в одном каталоге 10 файлов "file1.txt, file2.txt ..." и заполнить их текстом названия:


$ ls
file10.txt file1.txt file2.txt file3.txt file4.txt file5.txt file6.txt file7.txt file8.txt file9.txt


$ cat file9.txt
file9.txt


LinuxCamp
❤‍🔥16👍8🔥741
1000 & 1 способ: решение

И так, было интересно посмотреть на ваши варианты, один из них даже пробил то, о чем пойдет речь.

Возможно, способ не самый минималистичный, но мне понравился используемый стек)

Сразу не пугайтесь, все разберем:


$ seq 1 10 | xargs -I{} bash -c "echo \"file{}.txt\" > file{}.txt"


1) seq 1 10 - генерирует последовательность чисел 1-10. Каждое число будет выведено в новой строке:


$ seq 1 10
1
2
3
...


2) конвейер '|' - используется для того, чтобы команда xargs получила на вход (STDIN) вывод (STDOUT) предыдущей команды seq.

В результате xargs будет работать с последовательностью 1-10;

3) "xargs -I{}" - утилита xargs позволяет выполнять произвольную команду для одного либо нескольких входных значений. В данном случае входные значения передаются через конвейер.

Мы детально ее разберем отдельно. Пока вам нужно знать только то, что xargs выполнит "bash -c" для каждого элемента от 1 до 10.

"-I{}" позволяет определить место входных данных в сгенерированной команде. По умолчанию они идут в конец. Вместо "{}" может быть что угодно. Это, своего рода, шаблон.

В результате каждый элемент 1-10 будет подставлен в нужное нам место внутри команды:


$ seq 1 10 | xargs -I{} echo "file{}.txt"
file1.txt
file2.txt
file3.txt


4) "bash -c" - ну тут-то вы уже подкованы).

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

Без доп. оболочки тут обойтись не получится, т.к. для перенаправления xargs не выполнит подстановку по шаблону.

Вернее, '>' вообще не будет частью xargs и отработает в первую очередь, еще до самой команды:


$ seq 10 | xargs -I{} echoo file{}.txt > file{}.txt
xargs: echoo: No such file or directory

$ ls
file{}.txt


5) "echo \"file{}.txt\" > file{}.txt" - строка, которую bash выполнит для каждого значения от 1 до 10 ({}).

"echo \"file{}.txt\" > file{}.txt" - записывает текст fileX.txt в файл fileX.txt. Сам файл создается при перенаправлении вывода, которое мы разбирали тут.

\"\" - экранирование символов, которое необходимо, чтобы избежать разрыва, т.к. строка команды также находится внутри двойных кавычек.

Обратный слэш сообщает bash, что кавычки - это часть текста, а не завершающий символ;

LinuxCamp
👍36🔥157❤‍🔥1
Автоматизация задач с xargs

Многие пользователи Linux никогда не слышали о команде xargs, хотя это мощный инструмент для автоматизации задач и запуска команд с разными аргументами.

Утилита обрабатывает входные данные из стандартного потока ввода (STDIN). Они могут туда поступать либо напрямую от пользователя либо от сторонних команд через конвейер '|'.

Рассмотрим простой пример. Предположим, вы находитесь в каталоге с тремя файлами:


$ ls -1
file1.txt
file2.txt
file3.txt


Передадим данный список в xargs, чтобы он служил входными данными, и "wc -l" в качестве шаблона команды:


$ ls -1 | xargs wc -l
3 file1.txt
4 file2.txt
1 file3.txt
8 total


В результате xargs применил шаблон команды "wc -l" к каждому файлу для подсчета строк.

Недостаток примера заключается в том, что xargs тут-то и не требуется, можно обойтись сопоставлением файлов с шаблоном:


$ wc -l *
3 file1.txt
4 file2.txt
...


Зачем тогда использовать xargs?

Ее мощь становится очевидной, когда входные строки немного сложнее.

Предположим, вы хотите обойти дерево каталогов и посчитать количество строк во всех python скриптах с именами, оканчивающимися на ".py".

Такой список путей к файлам легко создать с помощью команды find:


$ find . -type f -name \*.py -print

/usr/lib/bup/bup/options.py
/usr/lib/bup/bup/xstat.py
...


Теперь xargs может применить шаблон команды к каждому файлу:


$ find / -type f -name \*.py -print | xargs wc -l

292 /usr/lib/bup/bup/options.py
112 /usr/lib/bup/bup/xstat.py
...


Комбинируя find и xargs, можно дать возможность любой команде выполняться с обходом всей файловой системы, затрагивая только те ресурсы, которые соответствуют критериям.

Команда xargs имеет множество опций. Рассмотрим наиболее интересные "-n", "-I" и "-0".

1. Параметр "-n" указывает то количество аргументов, которое будет передано на 1 выполнение команды:


$ ls | xargs echo
file1.txt file2.txt

$ ls | xargs -n1 echo
file1.txt
file2.txt


Во втором случае, команда echo выполнится 2 раза - по вызову на аргумент.

2. Параметр "-I" определяет место входных строк в команде. По умолчанию они добавляются в конец, но вы можете настроить их отображение в другом месте.

После "-I" введите любую строку, и она станет прототипом, указывающим, куда следует вставлять аргументы:


$ ls | xargs -I XYZ echo XYZ is OK
file1.txt is OK
file2.txt is OK


Обратите внимание, что "-I" ограничивает xargs одной входной строкой на команду.

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

3. Параметр "-0" использует символ "\0" в качестве разделителя данных, вместо "\n" или пробела.

Часто используется при объединении find и xargs, т.к., обычно xargs ожидает, что строки будут разделены пробелами.

А если отдельные элементы в строках содержат дополнительные пробелы, например имена файлов?

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

Например, если входные данные включают "file num 1.txt", xargs обработает все по отдельности и, вероятно, выведет ошибку:


$ find ./ -type f -name \*.txt -print | xargs wc -l

wc: ./file: No such file or directory
wc: num: No such file or directory
wc: 1.txt: No such file or directory


Как разделить входные строки нулями вместо символов новой строки? К счастью, у команды find есть возможность сделать это с помощью флага "-print0":


$ find ./ -name \*.txt -print0

./file1.txt./file num 1.txt


Теперь xargs будет искать разделитель "\0" и по нему сформирует корректный список аргументов для "wc -l":


$ find ./ -name \*.txt -print0 | xargs -0 wc -l

0 ./file1.txt
0 ./file num 1.txt
0 total


LinuxCamp
👍52🔥14❤‍🔥6
Xargs и флаги: -L, -t

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

1. И так, начнем с "-t". Флаг позволяет нам наглядно увидеть то, как xargs вызывает команду и какие аргументы ей передает.

Его полезно использовать для лучшего понимания принципа работы утилиты.

В следующем примере мы найдем все файлы с расширением .txt, разобьем список аргументов по разделителю "\0" и подсчитаем количество строк для каждого элемента:


$ find ./ -name \*.txt -print0 | xargs -0 -t wc -l


Сразу после выполнения нам выведется строка с общим видом выполняемой команды:


wc -l ./file1.txt ./file2.txt './test document.txt'

3 ./file1.txt
10 ./file2.txt
15 ./test document.txt


Можем убедиться в том, что "wc -l" выполнился 1 раз с вот таким длинным списком аргументов. Далее будем использовать "-t" для просмотра и разбора вызовов.

2. Переходим к "-L". Эта вещь позволяет нам указать, сколько строк будет передано на каждый вызов команды.

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


$ ls | paste - -
file1.sh file2sh
file3.sh file4.sh


Тогда все просто - xargs передаст команда столько аргументов, сколько найдет в каждой строке:


$ ls | paste - - | xargs -t -L1 wc -l

wc -l file1.sh file2.sh
...
wc -l file3.sh file4.sh


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


$ ls | sed -e "p;s/.txt$/.sh/" | xargs -L2 mv


Давайте разберем по частям:


$ ls | sed -e "p;s/.txt$/.sh/"

file1.txt
file1.sh
file2.txt
file2.sh


Вывод команды ls передается на вход для sed, после чего тот печатает изначальные строки и те, в которых изменено расширение.

В следующей части вывод sed передается команде xargs, которая выполняет mv по 1 разу для каждых 2 строк. Внедрим параметр "-t" для наглядности:


$ ... | xargs -L2 -t mv

mv file1.txt file1.sh
mv file2.txt file2.sh


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


$ ls | sed -e "p;s/.txt$/.sh/" | tr "\n" "\0" | xargs -L2 -t -0 mv


Команда 'tr "\n" "\0"' заменяет символы, а флаг "-0" теперь воспринимает за разделитель только символ "\0".

LinuxCamp
🔥21👍107
Xargs в действии

Прошлые 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
👍267❤‍🔥64
Раскрываем завесу тайн над устройствами

Для многих пользователей 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❤‍🔥32
Не самый стандартный способ использовать syslog

Расскажу историю о том, как очередная хотелка заказчика заставила меня немного под другим углом взглянуть на 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) убрать из вывода всю ненужную инфу (предупреждения, ошибки и т.д.):


$ 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❤‍🔥32
Познаем brace expansion

Продолжаем серию постов по спецсимволам оболочки: (), $(), []. Сегодня говорим про расширение фигурных скобок (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🔥238👎1🤔1💘1
Копирование и вставка "по уму"

Вы наверняка умеете работать с копированием и вставкой через сочетания клавиш: 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❤‍🔥33🤷‍♂1👏1
Прокачиваемся в grep

При работе в командной строке невозможно обойтись без 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🔥179❤‍🔥3
Ничего лишнего, только head и tail

Утилиты 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🔥84❤‍🔥1
Прокачиваемся в find

Поиск файлов и каталогов через 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🔥98❤‍🔥41👏1
Прокачиваемся в cp

У вас хоть одна пользовательская сессия проходит без копирования файлов?) В общем-то для этого мы и используем команду 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🔥186
Как я потрошил iso образ

Был обычный рабочий день: я усердно делил пиццу на равные части. Все шло гладко, как вдруг прилетает тикет с крайне необычным багом - в 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❤‍🔥32🤔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
👍52🔥9❤‍🔥5
Настройка прав по умолчанию

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


$ 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
This media is not supported in your browser
VIEW IN TELEGRAM
Когда уронил прод и готовишься пересекать границу вплавь)

LinuxCamp | #memes
😁44👍76
Как получить доступ к данным iso образа?

Когда я решал проблему с переделкой 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👏51