Иногда мне нужно написать текст, а затем передать этот текст в другую команду. Мой обычный рабочий процесс выглядит примерно так:
vim
# I edit and save my file as file.txt
cat file.txt | pandoc -o file.pdf # pandoc is an example
rm file.txt
Я нахожу это громоздким и пытаюсь изучить bash-скрипты, и я хотел бы сделать этот процесс намного проще, написав команду, которая запускает редактор и когда редактор закрывает канал, выводит его в stdout. Тогда я смогу выполнить команду как quickedit | pandoc -o file.pdf
.
Я не уверен, как это будет работать. Я уже написал функцию для автоматизации этого, следуя точному рабочему процессу, указанному выше, плюс некоторые дополнения. Он генерирует случайную строку в качестве имени файла и передает ее в vim при вызове функции. Когда пользователь выходит из vim, сохраняя файл, функция выводит файл на консоль, а затем удаляет файл.
function quickedit {
filename="$(cat /dev/urandom | env LC_CTYPE=C tr -cd 'a-f0-9' | head -c 32)"
vim $filename
cat $filename
rm $filename
}
# The problem:
# => Vim: Warning: Output is not to a terminal
Проблема, с которой я вскоре столкнулся, заключается в том, что когда я делаю что-то вроде quickedit | command
самого vim, его нельзя использовать в качестве редактора, потому что весь вывод ограничен каналом.
Мне интересно, есть ли какие-нибудь обходные пути к этому, чтобы я мог передать вывод своей quickedit
функции. Неоптимальной альтернативой является запуск отдельного редактора, скажем, возвышенного текста, но я действительно хочу остаться в терминале.
:w !pandoc -o file.pdf
? (Примечание: пробел междуw
и!
является существенным.)mktemp
а не изобретать его небезопасным способом.Ответы:
vipe
это программа для редактирования конвейеров:Вы получаете редактор с полным выводом
command1
, а при выходе содержимое передается поcommand2
каналу.В этом случае нет
command1
. Итак, вы можете сделать:Или:
vipe
поднимает наEDITOR
иVISUAL
переменных, так что вы можете использовать их , чтобы получить его , чтобы открыть Vim.Если он не установлен,
vipe
он доступен вmoreutils
пакете;sudo apt-get install moreutils
или каков бы ни был эквивалент вашего аромата.источник
moreutils
доступно на Homebrew.moreutils
доступно для установки через pkg (8) .Вы можете сделать это из Vim:
Или даже записать буфер в сложный конвейер:
И тогда вы можете выйти из Vim без сохранения:
Однако, учитывая ваш конкретный вариант использования, вероятно, есть лучшее решение, если использовать его в
vi
качестве редактора командной строки. Предполагая, что вы используетеbash
:Это устанавливает ваши сочетания клавиш в
vi
. Таким образом, вы можете редактировать свои команды прямо в командной строке с помощью основныхvi
сочетаний клавиш, нажимая<Esc>
и затем вводяvi
такие команды, какx
,cw
и т. Д. (Вы можете вернуться в режим вставки, нажавi
.)Что еще лучше и более актуально для этого вопроса, вы можете открыть Vim для непосредственного создания содержимого командной строки. Просто введите
<Esc>v
и вы получите пустой буфер Vim. При сохранении и выход, то есть команда на командную строку и немедленно бежать. Это гораздо более гибко, чем редактирование в командной строке напрямую, так как вы можете написать целый мини-скрипт, если хотите.Так, например, если вы хотите написать какой-нибудь хитрый текст и сразу передать его в pandoc, вы можете просто набрать:
Затем редактируйте буфер Vim, пока не получите что-то вроде:
Затем сохраните и выйдите (с
:x
), и все это будет выполнено как команда оболочки.Он также будет доступен в истории команд вашей оболочки.
источник
EDITOR
переменной среды значениеvim
и нажав,Ctrl-X
а затемCtrl-E
редактируя командную строку.Работает в трубопроводе
Пытаться:
Ключ в том, что для
vim
нормального использованияvim
необходимо, чтобы stdout был терминалом. Мы осуществляем это здесь с помощью перенаправления>/dev/tty
.В целях безопасности я поместил временный файл в домашний каталог пользователя. Подробнее об этом см. В разделе часто задаваемых вопросов Грега Вопрос 062 . Это избавляет от необходимости использовать скрытое имя файла.
Пример:
Когда
vim
открывается, я печатаюThis function succeeded.
и сохраняю файл. Результат на экране выглядит так:Несмотря на то, что выходные данные
quickedit
перенаправляются в конвейер, они по-vim
прежнему работают нормально, потому что мы дали ему прямой доступ/dev/tty
.Запуск программы из vim
Как я уже упоминал в комментариях, vim может передать файл команде. Например, изнутри vim введите команду
:w !pandoc -o file.pdf
(Примечание: пробел между w и! Необходим).источник
trap '...' exit
не удается, но,trap '...' EXIT
кажется, работает. Я не знаю много о захвате, но мой общий подход к временным файлам заключается в использованииmktmp [--suffix=...]
. Кроме того,vim <outfile> -c '...' >/dev/tty
работает как обычно, пока файл не загружен, затем выполняет заданную цепочку команд, в том числе,:wq
если вы хотите пропустить этап редактирования. Я тоже использовалset | grep -a EXIT
и нашелsignals=(EXIT ... DEBUG)
.Убедитесь, что
vim
он установлен в качестве вашего редактора по умолчанию (например,export EDITOR=vim
в вашем.bash_profile
или.bashrc
. Затем, в любом приглашении, вы можете ввести Ctrl-, Xа затем Ctrl- E. Это откроет вашу текущую командную строку в настроенном редакторе (напримерvim
). Внесите изменения, сохраните и выйти, и команда будет выполнена так, как если бы вы ввели ее в командной строке, включая конвейеры и тому подобное.источник