Командный интерфейс (CLI, Command-Line Interface) – формальный язык взаимодействия человека с вычислительной системой посредством текстовых команд. С информатической точки зрения CLI – это конкретизация интерпретируемого языка управления, для которого определены алфавит, лексика, грамматика, правила вывода и семантическое соответствие командам операционной системы. Владение CLI развивает умение формализовать алгоритмы, работать с потоками данных, строго трактовать предикаты и параметры – все это напрямую полезно при подготовке к ЕГЭ по информатике (анализ алгоритмов, логика ветвлений, работа с файлами и процессами, оценка сложностей).
Ниже представлен академический разбор: формальные определения, минимальная грамматика, семантика потоков и конвейеров, правила кавычек и подстановок, модель завершения и диагностики, межплатформенные различия (Windows CMD/PowerShell vs Unix-подобные оболочки), шаблоны и анти-ошибки. В конце – 5 упражнений в экзаменационном стиле.
Лексемы и алфавит
Обозначим:
Σ – алфавит символов Unicode;
Ops – множество служебных символов оболочки (|, >, <, &, ;, (, ), *, ?, ', ", `, \ и т. п.);
WS – пробельные символы.
Лексемы:
IDENT ::= (буква | '_' | '.') { буква | цифра | '_' | '.' | '-' }
NUMBER ::= цифра { цифра }
QSTR ::= '"' { любой_символ_кроме_" | экранирование } '"'
| '\'' { любой_символ_кроме_' } '\''
OP ::= один или два служебных символа (например, |, >, >>, 2>, &&, ||)
WS ::= пробельные символы
Мини-грамматика (БНФ-приближение)
<commandline> ::= <pipeline> { (';' | '&&' | '||') <pipeline> } [ ';' ]
<pipeline> ::= <simple> { '|' <simple> }
<simple> ::= [ <redir>* ] <call> [ <redir>* ]
<call> ::= <word> { <word> }
<word> ::= IDENT | NUMBER | QSTR | <subst> | <glob>
<redir> ::= ('>' | '>>' | '2>' | '<' | '&>' ) <word>
<glob> ::= шаблон_имён_файлов с '*' и '?' (раскрывается оболочкой)
<subst> ::= '$(' <commandline> ')' # подстановка результата другой команды
Операционная семантика
Вызов: первый <word> в <call> – имя исполняемого файла или встроенной команды; последующие <word> – её аргументы.
Код возврата: целое неотрицательное (в Unix 0 – «успех», ≠0 – «ошибка»).
Потоки: stdin (0), stdout (1), stderr (2). Конвейер A | B соединяет stdout(A) со stdin(B).
Окружение: пары ИМЯ=ЗНАЧЕНИЕ, доступные дочерним процессам.
Оболочка выполняет расширения в предсказуемом порядке (вариации зависят от диалекта, но общий принцип стабилен):
Правило R1 (сохранение границ): чтобы вывести содержимое подстановки как один аргумент, заключайте $(...) в двойные кавычки:
echo "$(some command producing words with spaces)"
Правило R2 (буквальность): одинарные кавычки '...' отменяют любые подстановки; двойные "...“ разрешают $VAR и $(...), но защищают пробелы.
Перенаправления (копировать как шпаргалку)
> file # stdout → файл (перезаписать)
>> file # stdout → файл (добавить)
2> file # stderr → файл
&> file # stdout и stderr вместе (bash/zsh)
< file # stdin из файла
2>&1 # присоединить stderr к stdout
Правило R3 (диагностика): разделяйте диагностический поток и обычный вывод. Если нужно объединить – делайте это явно (2>&1), чтобы понималось из кода.
Конвейеры и их сложность
prod | filt | cons – ленивый поток байтов; типичная трудоёмкость – O(n) по размеру входа при условии, что фильтры не буферизуют весь поток.
Правило R4 (стриминг): пишите фильтры, работающие построчно/порциями; избегайте полного чтения в память без необходимости.
Логические операторы
cmd1 && cmd2 # cmd2 выполняется только при успешном завершении cmd1 (код 0)
cmd1 || cmd2 # cmd2 выполняется, если cmd1 завершилась с ошибкой (код ≠0)
Правило R5 (логическая строгість): опирайтесь на код возврата, а не на «пустой/непустой вывод».
Позиционные параметры (bash-скрипт)
$0 – имя скрипта
$1..$n – аргументы
$# – количество аргументов
"$@" – все аргументы С СОХРАНЕНИЕМ границ
Правило R6 (границы слов): всегда используйте "$@" вместо $@/$*, иначе аргументы с пробелами «распадутся».
Функции оболочки и контракты
sum() {
# Предусловия (контракт):
# - на входе: два целых; на выходе: сумма в stdout; код 0 при успехе
local a="$1" b="$2"
echo $((a + b))
}
Правило R7 (контракт): документируйте предусловия/постусловия: что функция читает из stdin, пишет в stdout/stderr, какие коды возврата использует.
|
Аспект |
Unix-оболочки (sh/bash/zsh) |
Windows CMD |
PowerShell |
|
Переменные |
$VAR, export VAR=... |
%VAR% |
$env:VAR=... |
|
Конвейер |
поток байтов |
поток байтов |
поток объектов (.NET) |
|
Подстановки |
$(), $VAR |
%VAR% |
подвыражения $(...), объекты |
|
Перенаправления |
>, >>, 2>, &> |
>, >>, 2> |
>, 2>, *>, Out-File |
|
Скрипты |
.sh с #!/bin/sh |
.bat/.cmd |
.ps1 |
Правило R8 (модель конвейера): в PowerShell по конвейеру «текут» объекты; фильтрация/сортировка семантически богаче, но текстовый вывод формируйте в конце, иначе легко разрушить объектность.
Пусть n – размер входа, k – число процессов в конвейере, τ_spawn – накладная на создание процесса. Тогда грубо:
Время ≈ O(n) + k * τ_spawn
Память ≈ O(буферов_каналов) (обычно константна по сравнению с n при потоковой обработке)
Правило R12 (минимизация процессов): группируйте операции, используйте встроенные средства (xargs, «многофункциональные» утилиты) и избегайте «форка в цикле», если это не нужно.

# Перенаправления
cmd >out.txt # stdout в файл (перезаписать)
cmd >>out.txt # stdout в файл (добавить)
cmd 2>err.txt # stderr в файл
cmd >out.txt 2>&1 # объединить stdout+stderr в out.txt
# Управление потоком выполнения
build && test || echo "TEST FAILED"
# Безопасный каркас bash-скрипта
set -euo pipefail
IFS=$'\n\t'
# Сохранение границ аргументов
for f in "$@"; do printf '%s\n' "$f"; done
Упражнение 1. Лексический и синтаксический разбор
Дан фрагмент:
cat "data set.txt" | grep -E "^[A-Z]{2}[0-9]{3}$" > out.txt 2> log.txt
a) Выполните разбиение на лексемы и классифицируйте их (OP/QSTR/IDENT).
b) Постройте дерево разбора по грамматике из §1.2.
c) Опишите потоки: что попадает в stdout, куда перенаправляется stderr, каково поведение при отсутствии файла data set.txt (укажите код возврата и последствия для конвейера).
Упражнение 2. Логика выполнения и коды возврата
Имеется команда:
compile src && run app || echo "FAIL"
a) Перечислите все комбинации кодов возврата compile и run, при которых напечатается "FAIL".
b) Перепишите так, чтобы "FAIL" выводилось только если провалился любой из этапов, но не дублировалось:
compile src && run app; rc=$?
[ $rc -eq 0 ] || echo "FAIL"
c) Обоснуйте эквивалентность формулы (compile ∧ run) → ¬echo.
Упражнение 3. Границы слов и корректный перебор
Исходно:
for f in $(ls *.txt); do cp $f backup/$f; done
a) Объясните, почему это решение некорректно при пробелах/переводах строк в именах.
b) Дайте исправленный вариант без потери границ:
mkdir -p "backup"
for f in *.txt; do
[ -e "$f" ] || continue
cp -- "$f" "backup/$f"
done
c) Оцените трудоёмкость и объясните, зачем здесь [ -e "$f" ].
Упражнение 4. Конвейер: байты против объектов
Сравните:
# PowerShell (объекты)
Get-ChildItem -File | Where-Object Length -gt 1000000 | Select-Object Name,Length
# Bash (байты)
find . -type f -size +1000000c -printf "%f %s\n"
a) Опишите различия модели данных (объекты vs строки).
b) Объясните, почему форматирование текста в PowerShell стоит откладывать до финала.
c) Предложите в bash сортировку результата по длине имени, сохранив потоковый характер (без полного чтения в память, если возможно).
Упражнение 5. Диагностика и воспроизводимость
Сформулируйте одну команду, которая:
– запускает analyze input.csv,
– пишет полезный вывод в report.txt,
– предупреждения/ошибки – в warn.log,
– на экран печатает только DONE при успехе, и FAIL при неуспехе.
Решение:
if analyze "input.csv" >"report.txt" 2>"warn.log"; then
echo "DONE"
else
echo "FAIL"
fi
Поясните, почему кавычки обязательны и что произойдёт при отсутствии файла input.csv.
Командные интерфейсы – это строго определённые языки управления системой, где каждое правило (кавычки, подстановки, порядок расширений, поведение потоков, коды возврата) имеет формальный смысл и практические последствия. Умение мыслить в терминах грамматики, семантики и инвариантов превращает работу с CLI в воспроизводимый и проверяемый процесс. Эти же навыки усиливают подготовку к ЕГЭ по информатике: вы лучше анализируете алгоритмы, корректно работаете с данными и уверенно управляете сложными последовательностями операций.