меньше: рекламировать terminfo через pipe

Это краткое представление файлов в текущем каталоге. bash расширит его до того же, что и вывод ls.
Пример - file{a,b}.txt расширяется до filea.txt fileb.txt в bash. Таким образом, что-то вроде cp file{a,b}.txt расширяется до cp filea.txt fileb.txt, что скопирует filea.txt в fileb.txt.

0
25.05.2019, 05:57
2 ответа

Это оболочка, которая устанавливает конвейер. lessв этом не участвует.

Когда вы выполняете ls | less, оболочка запускает lsи lessодновременно после создания stdout процесса, который в конечном итоге выполнит lsзапись конца канала и stdin того, который будет выполняться. выполнить lessконец чтения той же трубы.

lsопределяет, что его стандартный вывод не является tty-устройством, и соответствующим образом изменяет свое поведение. lessничего не может с этим поделать.

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

Другим подходом может быть получение третьего процесса, который считывает выходные данные lsчерез пару псевдотерминалов -и передает их lessчерез конвейер, как @JdeBP ptyrunили ptybandage, или expectunbuffer, или с помощью zshzptyвстроенной:

zmodload zsh/zpty
ttypager() { (zpty c "stty raw -echo; ${(q)@}"; zpty -r c) | less -RFX; }

ttypager ls

lsбудет работать в новом сеансе в новом терминале, поэтому не будет получать SIGINT при нажатии ^C или SIGPIPE при выходе из lessдо завершения записи. Однако, поскольку процесс, удерживающий главную сторону (подоболочкой здесь ), все еще будет в этих случаях lsполучать SIGHUP и, тем не менее, умирать.

zptyздесь запускает команду, как если бы она использовала eval, так что псевдонимы будут расширены. Фактически,они будут расширены, даже если вы вызовете ttypager \ls, так как ttypagerвсе равно получит lsв качестве аргумента и позже выполнит расширение псевдонима.

Также обратите внимание, что и stdout, и stderr отправляются на этот псевдо-терминал -и, в конечном итоге, в канал.

Это все еще немного грязный хак. Здесь самым простым было бы указать lsвести себя так, как если бы он был подключен к терминалу.

Вы можете использовать вспомогательную функцию, например:

paged_ls() { ls -C --color=always "$@" | less -RFX; }

Где -Cпринудительно выводит вывод в столбце (, что некоторые реализации, включая GNU ls, делают по умолчанию, когда вывод идет на терминал )и --color=alwaysпринудительно выводят вывод в цвете независимо от того, является ли вывод идет к терминалу или нет.

5
28.01.2020, 02:15

Общий способ сделать это — использовать такие инструменты, как инструмент Бернштейна ptybandage:

$ ptybandage ls > wibble ; less wibble
.

Или, лучше в данном случае, Бернштейнаptyrun:

$ ptyrun ls | less

Дополнительная литература

  • https://unix.stackexchange.com/a/249801/5132
  • Даниэль Дж. Бернштейн (1996 ).ptyrun. djbwares .
  • Даниэль Дж. Бернштейн (1996 ).ptybandage. djbwares .
  • Джонатан де Бойн Поллард (2014 ).ptyrun. Направляющая ноша . Программное обеспечение.
  • Джонатан де Бойн Поллард (2014 ).ptybandage. Направляющая ноша . Программное обеспечение.
0
28.01.2020, 02:15

Теги

Похожие вопросы