docker exec -it df0 shdocker exec -it df0 sh -c "bash || ash || sh"docker exec -it pg psql -U postgres -d postgresdocker compose exec postgres psql -U postgresdocker cp transactions.csv namenode:/transactions.csvID контейнера можно сокращать до любого однозначного префикса — df0 вместо полного хеша. Экономит копирование из docker ps каждый раз.
bash есть не везде: в образах на Alpine его нет, и docker exec -it X bash падает с executable file not found. Цепочка bash || ash || sh закрывает вопрос одной командой, не заставляя выяснять, на чём собран образ.
Запускать клиент напрямую обычно удобнее, чем заходить в оболочку и оттуда вызывать его руками: короче и не оставляет лишнюю интерактивную сессию.
Через docker compose exec обращение идёт по имени сервиса из compose-файла — оно стабильно, в отличие от имени контейнера, куда compose подставляет префикс проекта и порядковый номер.
-it нужен именно для интерактива. Для разовой команды в скрипте флаги лучше убрать: без терминала -t иногда ломает вывод, а в CI его может не быть вовсе.