Действительно ли zsh может получить доступ к stdout последней запущенной программы?

Можно скопировать шрифты в в ~/.fonts папка и выполненный fc-cache -fv управляйте для кэширования их. Чтобы сделать это, Вам не нужны административные привилегии.

14
13.04.2017, 15:37
3 ответа

В большинстве эмуляторов терминала нет функции захвата вывода с экрана. Я, кажется, припоминаю автора xterm («эталонного» эмулятора терминала), который заявил, что реализовать его будет сложно. Даже если бы это было возможно, оболочка должна была бы отслеживать, где было последнее приглашение.

Таким образом, вам не избежать повторного запуска команды, если вы не используете специфичный для терминала ручной механизм, такой как копирование и вставка с помощью мыши в xterm или с клавиатуры в Screen.

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

Вы можете повторно запустить команду и записать ее вывод. Есть разные способы сделать каждый. Чтобы повторно запустить команду, вы можете использовать:

  • !! подстановка истории - наиболее удобно набирать;
  • fc -e - , которую можно использовать в функции.

Для захвата вывода вы можете использовать подстановку команд или функцию, подобную следующей:

K () {
  lines=("${(f@)$(cat)}")
}
!! |K

Это устанавливает массив строк как результат команды, переданной в него.

6
27.01.2020, 19:51
[119342]Вот первый отрезок чего-то, чтобы поместить последнюю строку вывода в переменную с именем [119865]$lastline[119866].

Здесь используется крюк zsh [119867]preexec[119868] для выполнения [119869]exec[119870] с [119871]tee[119872] для хранения копии stdout команды, затем с помощью [119873]precmd[119874] для чтения сохраненного вывода и восстановления stdout, чтобы он был просто терминалом для отображения запроса.

Но все равно нужно немного поработать. Например, так как stdout больше не является терминалом, такие программы как [119875]vim[119876] и [119877]less[119878] работают некорректно.

  1. В этих вопросах есть некоторая полезная информация:
  2. Могу ли я настроить оболочку на печать STDERR и STDOUT разными цветами?
  3. Показывать только stderr на экране, но записывать как stdout, так и stderr в файл
3
27.01.2020, 19:51

Я придумал это половинчатое -испеченное решение:

alias -g ___='"$(eval "$(fc -ln -1)" | tail -n 1)"'

Это позволяет вам написать ___в любой точке командной строки. Предыдущая команда будет повторно запущена -, а ___будет заменена последней строкой ее вывода. Пример использования:

$ touch foo bar baz
$ ls -1
bar
baz
foo
$ vim ___

Последняя команда будет расширена до vim foo.

У него действительно есть острые края!

  • Если вы включили ___в команду, но предыдущая команда также включала ___, оболочка на некоторое время зависнет в каком-то странном состоянии. Вы можете немедленно выйти из этого состояния с помощью Ctrl-C .

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

  • Некоторые команды будут отображать разные выходные данные при «обычном» запуске и при подключении к каналу. (Сравните вывод lsи ls | cat. )Если команда, вызванная ___, является одной из этих, вы можете в конечном итоге запустить команду, отличную от ожидаемой.

  • И, конечно же, если вы хотите сделать что-то с выходной строкой, отличной от последней, это вам не поможет.

Я выбрал имя ___, потому что никогда не хотел включать его как слово в командную строку, даже как аргумент. Вы можете выбрать другое имя, но будьте осторожны, чтобы не выбрать что-то, что может быть расширено для вас непреднамеренно.

2
27.01.2020, 19:51

Теги

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