Каждая из заметок – моя шпаргалка на пару, чтобы не забыть, что по плану нужно рассказать (по сути – тезисы) + расшифровка, чтобы было понятно и неподготовленному читателю. Так что будьте аккуратны – с каждой заметкой вы становитесь чуть ближе к высшему образованию в областях "компьютерные науки" и "компьютерная безопасность".
До начала пары вспомнили 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
Если коротко:
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 базовых возможности:
Конкатенация (вспоминаем
cat
) — два выражения могут идти одно за другим. Полученное большое выражение будет соответствовать входной строке тогда и только тогда, когда часть входа, соответствующая первому маленькому выражению, сразу же следует за частью, которая соответствует второму маленькому выражению.ab
Объединение (операция
or
/||
) — большое выражение соответствует строке, соответствуйщей одному из маленьких выражений, содержащихся в нём.a|b
Замыкание — маленькое выражение может быть «повторено» ноль или более раз, чтобы соответствовать входу.
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
ДЗ
Проверю через пару — буду предвзят, требовать странное. Пройдусь по всем, у всех посмотрю.
Кто хочет — может в конце этой показать.
По результатам буду проставлять успеваемость за полусеместр.