Поведение ввода Stdin между «cat» и «less»

Поведение ввода Stdin между «cat» и «less»

Когда я выдаю cat, терминал зависает в ожидании ввода stdin. Однако когда lessвыдается , я получаю Missing filename ("less --help" for help). Известно, что lessи catпринимает ввод stdin. В чем разница? Как это отражено в man-страницах?

решение1

lessзапускает следующий код, когда ему не указаны аргументы имени файла:

if (isatty(fd0))
{
    error("Missing filename (\"less --help\" for help)", NULL_PARG);
    quit(QUIT_OK);
}
return (edit("-"));

Он жалуется, когда стандартный ввод — это терминал. Если стандартный ввод — это обычный файл или канал, то с этим все в порядке.

Вероятно, это происходит потому, что в конце каждой страницы необходимо считывать ответы с терминала, и нет возможности отличить данные, которые выгружаются, от ответов.

Об этом не упоминается на странице руководства. Может быть, так и должно быть.

catне разбивает вывод на страницы и не читает ответы с терминала. У него нет никаких ограничений, поскольку stdin является терминалом.

решение2

Я предполагаю, что это lessвызовы isatty(3)файлового дескриптора 0. Другой альтернативой было бы вызвать fstat(2)файловый дескриптор 0 и интерпретировать значения полей st_inoи st_rdev. В любом случае, суть в том, что программа может что-то сказать о файловом дескрипторе, а stdin — это просто файловый дескриптор 0.

Что касается того, почему lessзавершается, а catпочему нет, вам нужно посмотреть на назначение двух разных программ. less— это пейджер GNU, реакция на пейджер BSD more(обратите внимание на каламбурное название). Не совсем имеет смысла разбивать на страницы ввод с терминала, но может иметь смысл разбивать на страницы ввод с конвейера. Любой из них может быть stdin. Кодирование особого случая в lessимеет смысл. Кодирование особого случая в catне имеет смысла и снижает его полезность. Даже в конце 1980-х годов у людей были оконные системы, и они печатали, cat > somefileа затем вставляли большой кусок текста в «somefile».

Связанный контент