Программы
Операционные системы. Linux. Bash && "продвинутый" Bash

Операционные системы. Linux. Bash && "продвинутый" Bash

bash, regexp, printf и другие интересности

Оговорюсь заранее:
Каждая из заметок – моя шпаргалка на пару, чтобы не забыть, что по плану нужно рассказать (по сути – тезисы) + расшифровка, чтобы было понятно и неподготовленному читателю. Так что будьте аккуратны – с каждой заметкой вы становитесь чуть ближе к высшему образованию в областях "компьютерные науки" и "компьютерная безопасность".

До начала пары вспомнили chmod, немного поговорили про sudo и chown:

sudo

sudo (англ. substitute user and do, дословно «подменить пользователя и выполнить») — программа для системного администрирования UNIX-систем, позволяющая делегировать те или иные привилегированные ресурсы пользователям с ведением протокола работы.

tldr: получить привелегии root (администратора системы).

Глянули /etc/passwd — список учёток.

Глянули /etc/sudoers — настройки использования sudo.

ДЗ: без использования утилит id, group написать утилиту вывода групп юзера. +5 баллов в карму.

chown

Команда смены владельца файла.

Чтобы сменить владельца файлов в директории и во всех поддиректориях (рекурсивно), выполните:

sudo chown -R user:group /home/user/path/to/directory/

Менять пользователя может только root, -R — рекурсивно.

Linux, bash. Однострочники

Собственно, начало пары.

|, &&, ||

Уже разбирали. Повторяем.

| — перенаправление вывода одной команды на вход другой. Пример:

man bash | less

|| — ленивое логическое "или". Используется для выполнения операции, если предыдущая завершилась с ошибкой:

cd /root || echo Доступ запрещён

&& — ленивое логическое "и". Используется для выполнения операции, если предыдущая завершилась успешно:

cd $HOME && echo Чуи, мы дома!

cat, head, tail, grep

cat — конкатенация содержимого файлов и вывод:

cat ~/.bash* | less

head — вывести начало файла (по умолчанию 10 строк):

head /etc/passwd

tail — вывести конец файла (по умолчанию 10 строк):

tail /var/log/syslog

— полезно для чтения логов — там как раз последнее — самое интересное. Также часто используется:

tail -f /var/log/syslog

— выводить по мере поступления новых строк в файл.

grep — великая утилита для фильтрации входного потока:

cat /etc/passwd | grep root
grep root /etc/passwd  # есть вариант указать в аргументах файлы

ДЗ: пишем anti-head-tail — 2 аргумента: с какой по какую строку отправлять на вывод. +5 баллов в карму.

xargs

Отдельная заметка про xargs.

Если коротко:

ls | xargs file  # передать спиок вывода ls аргументом утилите file.

# Склеить строки
echo "a
b
c" | xargs
a b c

regexp

Oh, shi~~

Короче, есть главная проблема программирования — "придумать название переменной".

За ней ровным строем идут регулярные выражения/грамматики, инвалидация кеша и реляционная алгебра.

Я вам не скажу за главную проблему, но за регулярные выражения немного поясню.

Мы уже встречались с прекрасными подстановками типа * и, например, *.txt. Видели забавные mkdir -p ./test/{a,s,d/{q,w,e}}, но что, если я скажу, что подобным образом можно искать?!

Как-то мы уже использовали grep для поиска подстроки в строке:

grep roo /etc/passwd

— ищем "roo" в файле passwd. Но это не так круто, как искать по шаблону!

grep '^root:' /etc/passwd

— находим запись пользователя root.

Отмечу, что в каком-то виде regexp (regular expressions) есть практически во всех языках программирования, поэтому мозголомка ниже будет полезна. Понимание regexp сродни пониманию сложения — рассказывать об этом также сложно, ибо уже не помнишь, в чём проблемы восприятия (поэтому жду вопросов).

Регулярные выражения содержат 3 базовых возможности:

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

    ab

  2. Объединение (операция or / ||) — большое выражение соответствует строке, соответствуйщей одному из маленьких выражений, содержащихся в нём.

    a|b

  3. Замыкание — маленькое выражение может быть «повторено» ноль или более раз, чтобы соответствовать входу.

    a*

Примеры регулярных выражений

Конкатенация трёх выражений "f", "oo|ee", "t". Само же выражение "oo|ee" — объединение выражений "oo" и "ee":

f(oo|ee)t  # соответствуют foot или feet

Закрытие/замыкание/кложура и тд:

a+     # соответствует "a" один или более раз
a*     # соответствует "a" 0 или более раз
a?     # соответствует "a" 0 или 1 раз
a{2,5} # сооветствует от 2 до 5 раз "a"
a{2}   # 2 раза
a{2,}  # от 2 раз
a{,5}  # до 5 раз

Делаем одно и то же разными способами:

a(0|1|2|3|4|5|6|7|8|9)  # соотвествует a0, a1 ... a9
a[0-9]  # то же самое, что и a(0|1|2|3|4|5|6|7|8|9), но используя класс символов
a[[:digit:]]  # то же самое, что выше, но с альтернативным синтаксисом
a\\d  # то же самое, но через "сокращённое написание"

Полезно знать:

^   # символ начала строки
$   # символ конца строки (не путать с \n — переводом строки)
.   # любой символ

Помните [[:digit:]]? Такого много:

[:alnum:]   [:cntrl:]   [:lower:]   [:space:]
[:alpha:]   [:digit:]   [:print:]   [:upper:]
[:blank:]   [:graph:]   [:punct:]   [:xdigit:]

С чем это едят:

[[ "sad day" =~ (sad|happy) ]] && echo "Что-то о настроении"
grep '^root:' /etc/passwd  # запись пользователя root
awk '/false$/ {print $0}' /etc/passwd  # найти всех, кто логинится в false
cat /etc/passwd | sed '/ *#/d; /^ *$/d'  # убрали комментарии из /etc/passwd и вывели

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

Advanced bash

[[ > [

[ (команда "test") и [[ (новый тест) используются для вычисления выражений. [[ работает только в Bash, Zsh и Korn shell. Также он более мощный. [ доступен в POSIX shells.

#POSIX
[ "$variable" ] || echo 'переменная не задана или пуста'
[ -f "$filename" ] || printf 'Файла (обычного) нет: %s\n' "$filename"

if [[ ! -e $file ]]; then
    echo "Файла нет, лидо он не доступен: $file"
fi

if [[ $file0 -nt $file1 ]]; then
    printf 'файл %s новее %s\n' "$file0" "$file1"
fi

Короче говоря, в bash мы используем [[ ]] — он новее, быстрее и т.д. Если имеем какую-нибудь старую POSIX-совместимую Unix оболочку, то используем [ ]. По большей части синтаксис [[ ]] и [ ] схож.

# Унарные операции
[[ -d $file ]]    # файл типа директория
[[ -e $file ]]    # файл любого типа (проверка на существование (exists))
[[ -f $file ]]    # обычный файл
[[ ! -f $file ]]  # не (обычный файл). "!" - отрицание
[[ -z $var ]]     # истина, когда переменная пуста (zero)
[[ -n $var ]]     # ложь  , когда переменная пуста (nonzero)
[[ -r $file ]]    # файл существует и доступен для чтения
[[ -w $file ]]    # файл существует и доступен для запись
[[ -x $file ]]    # догадайтесь сами

# Сравнение строк (лексикографический порядок)
[[ a    <  b   ]]
[[ dog  >  cat ]]
[[ sh   =  sh  ]]
[[ bash != sh  ]]

# Сравнение чисел
[[ 5   -lt 10 ]]  # less than
[[ 100 -gt 99 ]]  # greater than
[[ 5   -eq 05 ]]  # equal
[[ 50  -ne 05 ]]  # not equal

# Логические операции
[[ -n $var && -f $var ]]  # переменная определеня и есть файл, указанный в ней.
[[ $(pwd) == $HOME || $(pwd) == '/' ]]  # мы в директории $HOME или в корне.

# Сравнение с шаблоном
[[ $(pwd) == $HOME/* ]]  # мы в поддиректории домашней папки или в ней

# Регулярные выражения
[[ $(date) =~ ^пятница ]] && echo Сегодня пара по ОСям

printf

printf — везде!

Его можно найти в bash, C, C++, python, perl, php, ...

По сути — форматированный вывод. Рассмотрим варианты шаблонов вывода:

%c Символ
%d Десятичное целое число со знаком
%i Десятичное целое число со знаком
%e Научный формат (строчная буква е)
%Е Научный формат (прописная буква Е)
%f Десятичное число с плавающей точкой
%g В зависимости от того, какой формат короче, применяется либо %e, либо %f
%G В зависимости от того, какой формат короче, применяется либо %E, либо %f
%o Восьмеричное число без знака
%s Строка символов
%u Десятичное целое число без знака
%x Шестнадцатеричное число без знака (строчные буквы)
%X Шестнадцатеричное число без знака (прописные буквы)
%% Знак %

Хех, не всё так просто!

  • Например, спецификатор %05d заполнит нулями пустующие позиции поля вывода, если количество цифр в целом числе, подлежащем выводу, будет меньше пяти.
  • Например, форматный код %10.4f выведет на экран число, у которого количество цифр не превышает 10, четыре из которых размещаются после десятичной точки.
  • На­пример, спецификатор %-10.2f выравнивает число с двумя знаками после точки по левому краю поля, состоящего из 10 позиций.

Немного примеров:

printf "%s\n" "Hello world"  # Вывести строку с переводом строки
printf "%.2f рублей" 2,3333333  # "2,33 рублей"
printf "\e[1;34m%.3d\e[0m\n" 42  # Вывести жирным синим цифры

Не успели. Всё же 2 пары за одну... Успели бы без ответов на вопросы. Но это не наш путь!

  • awk
  • раскраска вывода
  • sed

ДЗ

Проверю через пару — буду предвзят, требовать странное. Пройдусь по всем, у всех посмотрю.

Кто хочет — может в конце этой показать.

По результатам буду проставлять успеваемость за полусеместр.

Также может быть вам интересно:

Всё в одном месте и удобно!

Рад, что снова стал преподавать в университете. Ещё в 2013-ом я бы написал с большой буквы, но…

Читать »

Немного о написании патентов

На днях зарегистрировали патент за моим авторством. Писать патенты — довольно забавное занятие — сильно отличается от какого-либо из реального мира.

Читать »
Фото Настройка журналирования (логирования) в Python с примерами

Настройка журналирования (логирования) в Python с примерами

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

Фото Шаблон разработки ПО — Model View Controller (MVC)

Шаблон разработки ПО — Model View Controller (MVC)

MVC - один из самых распространённых архитектурных шаблонов разработки. Часто используется в различных фреймворках. В том числе и в Django.

Фото Так ли безопасен Linux? Несколько коммитов с уязвимосятми в stable

Так ли безопасен Linux? Несколько коммитов с уязвимосятми в stable

Исследователи сумели пройти code-review с реквестами в ядро Linux, заведомо содержащими добавление уязвимостей.

Фото Маленькая книга о Go (golang)

Маленькая книга о Go (golang)

Маленькая книга о Go распространяется под лицензией Attribution-NonCommercial-ShareAlike 4.0 International license. Вы не должны платить за эту книгу.

Фото И снова sudo, и снова "решето"

И снова sudo, и снова "решето"

В утилите sudo была исправлена очередная уязвимость.

Фото О многозадачности и планировщике задач (шедулер)

О многозадачности и планировщике задач (шедулер)

Небольшой экскурс в проблемы многозадачности и реализации планировщиков.

Фото Важна ли Операционная Система для программиста?

Важна ли Операционная Система для программиста?

Влияет ли выбор операционной системы на возможности программиста? Какую ОС выбрать конкретному разработчику?

Фото Как работает Web (этот ваш интернет)

Как работает Web (этот ваш интернет)

Пришло время феерически расставить точки над i в вопросе "а вот есть бекенд и фронтенд, а зачем?"