Почему находит имя файла | xargs vim вызывает странное поведение терминала?

Когда я делаю «locate 50local.policy | xargs vim», я получаю сообщение об ошибке «Vim: Warnung: Die Eingabe kommt nicht von einem Terminal» (перевод: Vim: Предупреждение: ввод не поступает с терминала).

Я могу успешно редактировать с помощью vim, но после того, как я его закрою, мой терминал ведет себя странно (я не могу набирать буквы, и когда я нажимаю ввод, приглашение оболочки просто повторяется. Когда я делаю это с помощью «xargs gedit», это не создает эти проблемы.

Я использую Ubuntu 11.10 с Gnome 3 и Gnome-Terminal 3.0.1.


person Konrad Höffner    schedule 22.11.2011    source источник


Ответы (3)


Vim ожидает подключения к реальному терминалу и отправляет соответствующие коды.

Сбросьте терминал с помощью

reset

Самый простой обходной путь:

locate 50local.policy | xargs gvim

Обоснование gui vim не требует терминала

В противном случае:

vim $(locate 50local.policy)

Обоснование vim запускается напрямую подключенным к терминалу (а не как дочерний процесс под xargs, который, в свою очередь, работает в подоболочке с подключением stdin/stdout к каналам вместо терминала ). Это как сказать

vim /usr/some/dir/50local.policy /usr/local/some/dir/50local.policy

Альтернативно

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

Пока в виме:

:args `locate 50local.policy`
:rewind

Это устанавливает список аргументов для файлов, возвращаемых командой оболочки между тиками; Затем :rewind переходит к первому файлу из этого списка. Если вы редактировали несколько совпадений, попробуйте следующее:

:w|next

Эта последовательность команд (разделенных символом |) записывает текущий буфер в файл, а затем переходит к следующему файлу в списке аргументов.

person sehe    schedule 22.11.2011
comment
Просто любопытно: в чем разница между vim $(...) и тем, что делает ОП? - person sidyll; 22.11.2011
comment
@sidyll Добавлены обоснования в пост - person sehe; 22.11.2011
comment
@sidyll OP использует xargs для создания процесса vim, а в другом случае процесс создается из оболочки. - person Philippe; 22.11.2011
comment
Спасибо, сехе и @Philippe. На самом деле я никогда не думал, что xargs выполнит команду сам по себе… - person sidyll; 22.11.2011
comment
@sidyll Дело в том, что xargs выполняет его с stdin/out, не подключенным к терминалу (выполнение echo hello | vim - имеет те же проблемы). - person sehe; 22.11.2011
comment
@eMPee584 спасибо за полезное редактирование. Я не могу проголосовать за это, но я бы :) - person sehe; 15.04.2013

Другой альтернативой является выполнение xargs с опцией -o. Со страницы руководства:

-o      Reopen stdin as /dev/tty in the child process before executing
        the command.  This is useful if you want xargs to run an interac-
        tive application.

Обратите внимание, что -o является расширением BSD для xargs.

Более портативное средство для достижения того же эффекта:

xargs sh -c 'vim "$@" < /dev/tty' vim
person mkomitee    schedule 13.11.2012

Хотя «сброс» устраняет проблему, вы также можете явно повторно активировать поведение эха с помощью:

stty echo
person Ruud van der Linden    schedule 04.09.2020