Что делают команды head и tail в Unix
Что проверяют
Умеете ли вы работать на сервере, где нет ни ноутбука, ни отладчика. Для питониста это косвенная проверка: человек, который смотрит трёхгигабайтный лог через open() в интерпретаторе, будет так же неаккуратен с памятью и в коде.
Как отвечать
head печатает начало потока, tail конец, по умолчанию обе по десять строк, обе читают и файл, и стандартный ввод. Дальше важны опции:
head -n 1 data.csv # только заголовок
tail -n 5 app.log # последние пять строк
tail -n +2 data.csv # всё начиная со второй строки
head -c 200 file.bin # первые 200 байт
tail -f app.log # следить за дописыванием
tail -F app.log # то же, но переоткрывать файл после ротацииЦенность в комбинациях: tail -n +2 data.csv | head -3 даёт три строки данных без заголовка, grep ERROR app.log | tail -20 показывает последние ошибки, head в конце конвейера обрывает тяжёлый вывод.
Практика, которую стоит назвать: посмотреть хвост лога сразу после падения воркера, оценить формат и разделители файла до того, как звать pandas.read_csv, вырезать маленькую выборку из большого выгруженного дампа для локальных тестов.
Где спотыкаются
Путают tail -n 5 и tail -n +5: первое это пять последних строк, второе это всё начиная с пятой. На пропуске заголовка в конвейере ошибка вылезает сразу, на большом файле её замечают уже в данных.
Забывают про буферизацию. tail -f app.log | grep ERROR может молчать минутами, потому что grep копит вывод блоками: нужен grep --line-buffered. Свой же скрипт при запуске в конвейере ведёт себя так же, и лечится это python -u или print(..., flush=True).
Не учитывают ротацию. tail -f держит открытым старый файл по его inode, и после переименования лога вы смотрите в пустоту, пока не заметите. Для постоянного наблюдения берут tail -F.