Этот проект представляет собой собственную реализацию базовых текстовых утилит Unix — cat и grep, написанных на языке Си. Разработка велась в строгом соответствии со стандартами POSIX и Code Style Google.
Основная цель проекта — глубокое погружение в системное программирование: работа с файловыми дескрипторами, управление памятью, использование библиотеки регулярных выражений (regex.h) и создание надежной архитектуры C-приложения.
Проект выполнен в рамках учебной программы Школы 21 от Сбера.
- Полная совместимость с GNU: Реализовано поведение оригинальных утилит Linux.
- Поддержка Regex:
s21_grepподдерживает поиск по регулярным выражениям. - Интеграционное тестирование: Написаны bash-скрипты, генерирующие тысячи тестовых кейсов и сравнивающие вывод с системными утилитами.
- Безопасность памяти: Код проверен на утечки (Valgrind / Leaks).
- Язык: C11
- Компилятор: gcc (
-Wall -Wextra -Werror -std=c11) - Библиотеки:
regex.h, стандартные библиотеки C. - Сборка: Makefile
Утилита для конкатенации и вывода содержимого файлов. Поддерживает комбинации флагов:
| Флаг | Описание |
|---|---|
-b (GNU: --number-nonblank) |
Нумерует только непустые строки. |
-e |
Отображает символы конца строки как $. |
-n (GNU: --number) |
Нумерует все выходные строки. |
-s (GNU: --squeeze-blank) |
Сжимает несколько смежных пустых строк в одну. |
-t |
Отображает табы как ^I. |
-v |
Отображает скрытые символы (кроме табуляции и конца строки). |
Утилита для поиска текста. Поддерживает сложные регулярные выражения и комбинации флагов:
| Флаг | Описание |
|---|---|
-e |
Шаблон поиска. |
-i |
Игнорирует регистр символов. |
-v |
Инвертирует поиск (выводит строки, НЕ соответствующие шаблону). |
-c |
Выводит только количество совпадающих строк. |
-l |
Выводит только имена файлов с совпадениями. |
-n |
Выводит номер строки перед совпадением. |
-h |
Подавляет вывод имен файлов в результатах. |
-s |
Подавляет сообщения об ошибках (например, о несуществующих файлах). |
-f |
Получает регулярные выражения из файла. |
-o |
Выводит только совпадающую часть строки. |
При разработке на macOS возникла проблема различия стандартов: macOS использует BSD реализацию утилит, в то время как задание требовало соответствия GNU стандартам (Linux).
Решение:
Для обеспечения корректности тестов я использовал пакет coreutils:
brew install coreutilsЭто позволило использовать gcat и grep в тестах. Мои скрипты (run_tests.sh)
git clone https://github.com/andreycoast/s21-simple-bash-utils.git
cd s21-simple-bash-utilsПроект собирается через make из корневых папок утилит.
Для s21_cat:
cd src/cat
makeДля s21_grep:
cd src/grep
makeУдаление объектных файлов и бинарников:
make cleanВывести файл с нумерацией всех строк и отображением спецсимволов:
./s21_cat -n -e tests/test_6.txtНайти все вхождения слова "int" (без учета регистра) в исходных файлах и вывести номера строк:
./s21_grep -in int *.cИспользование регулярного выражения (найти строки, начинающиеся с "void"):
./s21_grep -e "^void" *.hДля проекта разработана система интеграционного тестирования на Bash.
Запуск тестов:
# В папке cat или grep
make testКак это работает:
- Скрипт генерирует случайные комбинации флагов и входных файлов.
- Запускает оригинальную утилиту (
cat/grep) и сохраняет вывод. - Запускает мою реализацию (
s21_cat/s21_grep). - Сравнивает результаты через
diff. - Если есть различия — тест фейлится и сохраняет логи.
.
├── README.md
├── materials
│ └── linters
│ └── .clang-format
└── src
├── cat
│ ├── Makefile
│ ├── run_tests.sh
│ ├── s21_cat.c
│ ├── s21_cat.h
│ └── tests/
└── grep
├── Makefile
├── run_tests.sh
├── s21_grep.c
├── s21_grep.h
└── tests/
С чем пришлось столкнуться:
- Парсинг аргументов: Реализация логики обработки флагов (особенно склеенных, вроде
-nbe) вручную, для лучшего понимания работыgetopt. - Regex в C: Управление памятью при компиляции регулярных выражений (
regcomp,regexec,regfree). Важно было избежать утечек при многократном использовании.
Чему я научился:
- Глубокому пониманию работы системных вызовов Unix.
- Написанию надежных Makefile для автоматизации рутины.
- Созданию собственных интеграционных тестов.