# mc — консольный клиент S3

Индекс LLMS: [llms.txt](/llms.txt)

---

S3-хранилища — стандарт де-факто для объектных бакетов, бэкапов и статики. Когда AWS CLI кажется избыточным, а веб-консоль неудобной, выручает MinIO Client (`mc`). Это консольный инструмент для любого S3-совместимого хранилища: MinIO, Yandex Cloud, AWS S3, Backblaze B2. Работает из коробки, не требует Python и настраивается за минуту.

## Установка

Скачиваю бинарник и делаю исполняемым:

```bash
curl -fsSL https://dl.min.io/client/mc/release/linux-amd64/mc \
  -o /usr/local/bin/mc && chmod +x /usr/local/bin/mc
```

Проверяю версию:

```bash
mc --version
```

Для macOS аналогично, через Homebrew:

```bash
brew install minio-stable/mc/mc
```

> [!NOTE]
> `mc` — один статический бинарник без зависимостей. Прекрасно работает в контейнерах и на минимальных образах.

## Добавление алиаса

Алиас — это именованное подключение к S3-эндпоинту. Без него каждая команда требует полного URL.

```bash
mc alias set myminio https://minio.example.com \
  AKIAIOSFODNN7EXAMPLE \
  wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
```

После этого `myminio` заменяет URL во всех командах. Список алиасов:

```bash
mc alias list
```

> [!TIP]
> В production не храни ключи в истории команд. Используй переменные окружения: `mc alias set prod ${S3_ACCESS_KEY} ${S3_SECRET_KEY} --api API-S3v4` и подставляй через `env`.

Для S3-совместимых сервисов с самоподписанными сертификатами:

```bash
mc alias set myminio https://minio.example.com \
  minioadmin minioadmin --api S3v4 --insecure
```

## Просмотр и навигация

Вывести список бакетов:

```bash
mc ls myminio
```

Рекурсивный листинг с содержимым:

```bash
mc ls --recursive myminio/backups/
```

Информация об объекте:

```bash
mc stat myminio/backups/db-2024-01.sql.gz
```

> [!WARNING]
> `mc ls` без `--recursive` показывает только бакеты верхнего уровня. Для навигации по папкам внутри бакета используй префиксы.

## Работа с бакетами

Создать бакет:

```bash
mc mb myminio/app-logs
```

Если бакет уже существует, `mc` сообщит об ошибке. Флаг `--ignore-existing` подавляет её:

```bash
mc mb --ignore-existing myminio/app-logs
```

Удалить пустой бакет:

```bash
mc rb myminio/app-logs
```

Для непустого бакета — с флагом force:

```bash
mc rb --force myminio/app-logs
```

## Работа с объектами

Посмотреть содержимое объекта в stdout (не скачивая):

```bash
mc cat myminio/config/latest.yaml
```

Удалить объект:

```bash
mc rm myminio/backups/old.sql.gz
```

Рекурсивное удаление по маске:

```bash
mc rm --recursive --force myminio/temp/*
```

> [!NOTE]
> `mc rm` без `--force` запрашивает подтверждение. В скриптах всегда используй `--force`.

Найти объекты по критерию:

```bash
mc find myminio --name "*.log" --older-than 30d
```

Комбинация с удалением:

```bash
mc find myminio --name "*.tmp" --exec "mc rm {path}" {}
```

## Загрузка и выгрузка файлов

Скопировать локальный файл в бакет:

```bash
mc cp /tmp/dump.sql myminio/backups/
```

Множественная загрузка:

```bash
mc cp ./uploads/* myminio/static/
```

Скачать объект локально:

```bash
mc cp myminio/backups/latest.tar.gz /tmp/
```

Скопировать между бакетами (или между алиасами):

```bash
mc cp myminio/archive/2024/ mys3/backup-2024/ --recursive
```

Флаги для управления потоком:

| Флаг | Назначение |
|------|------------|
| `--recursive` | Обработать директории рекурсивно |
| `--force` | Перезаписать без вопросов |
| `--preserve` | Сохранить атрибуты файла (mtime, ACL) |
| `--if-not-exists` | Пропустить уже существующие объекты |
| `--disable-multipart` | Загрузить одним PUT-запросом |

## Зеркалирование

Односторонняя синхронизация директорий:

```bash
mc mirror /data/myminio/uploads
```

С флагами для прода:

```bash
mc mirror --overwrite --delete \
  /data/myminio/uploads
```

| Флаг | Назначение |
|------|------------|
| `--overwrite` | Перезаписать изменившиеся файлы |
| `--delete` | Удалить в приёмнике файлы, отсутствующие в источнике |
| `--watch` | Режим отслеживания изменений в реальном времени |
| `--md5` | Проверять MD5 после загрузки |

> [!WARNING]
> `--delete` опасен: удалит файлы в приёмнике, которых нет в источнике. Тестируй с `--dry-run` или с флагом `--preserve` для резервных копий.

Dry-run — показать, что будет сделано, без изменений:

```bash
mc mirror --overwrite --delete --dry-run \
  /data/myminio/uploads
```

## Политики доступа

Установить публичный доступ на бакет:

```bash
mc anonymous set download myminio/public
```

Типовые политики:

```bash
# Только чтение для всех
mc anonymous set download myminio/public

# Полный публичный доступ
mc anonymous set public myminio/public

# Приватный (только по ключам)
mc anonymous set private myminio/private

# Запретить листинг, разрешить скачивание по точной ссылке
mc anonymous set uploadOnly myminio/uploads
```

Посмотреть текущую политику:

```bash
mc anonymous list myminio
```

Сгенерировать пресигненную ссылку (работает и для приватных бакетов):

```bash
mc share download --expire 48h \
  myminio/backups/db-2024-01.sql.gz
```

Вывод содержит URL с подписью и время жизни.

## Полезные флаги

Глобальные флаги, работающие для любой команды:

| Флаг | Назначение |
|------|------------|
| `--debug` | Подробный вывод HTTP-запросов и ответов |
| `--json` | Вывод в JSON (удобно для парсинга в скриптах) |
| `--no-color` | Отключить цветной вывод |
| `--insecure` | Не проверять TLS-сертификат |
| `--config-dir` | Путь к конфигурации (по умолчанию ~/.mc) |
| `--limit` | Ограничить скорость (например, `--limit 10MiB/s`) |

JSON-вывод для автоматизации:

```bash
mc ls --json myminio | jq -r '.key'
```

Прогресс при копировании больших файлов:

```bash
mc cp --progress large.iso myminio/backups/
```

## Shell-completion

Автодополнение в bash/zsh экономит время:

```bash
# Bash
mc completion bash > /etc/bash_completion.d/mc

# Zsh
mc completion zsh > "${fpath[1]}/_mc"

# Fish
mc completion fish > ~/.config/fish/completions/mc.fish
```

После подключения набираешь `mc ` и два раза Tab — видишь доступные команды и алиасы.

---

`mc` покрывает 90% задач при работе с S3. Для сложных сценариев (версионирование, жизненные циклы, шифрование) — API или Terraform-провайдер. Но базовые операции с бакетами и объектами закрываются этим инструментом быстрее, чем через любой SDK.
