A veces necesito escribir texto y luego canalizar ese texto a otro comando. Mi flujo de trabajo habitual es más o menos así:
vim
# I edit and save my file as file.txt
cat file.txt | pandoc -o file.pdf # pandoc is an example
rm file.txt
Encuentro esto engorroso y busco aprender scripts de bash. Me gustaría simplificar el proceso escribiendo un comando que abre un editor y cuando el editor cierra la salida del editor a stdout. Entonces podría ejecutar el comando como quickedit | pandoc -o file.pdf
.
No estoy seguro de cómo funcionaría esto. Ya escribí una función para automatizar esto siguiendo el flujo de trabajo exacto anterior más algunas adiciones. Genera una cadena aleatoria para actuar como un nombre de archivo y se la pasa a vim cuando se invoca la función. Cuando el usuario sale de vim guardando el archivo, la función imprime el archivo en la consola y luego lo elimina.
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
El problema que pronto encontré es que cuando hago algo como quickedit | command
vim en sí mismo no se puede usar como editor porque toda la salida está restringida a la tubería.
Me pregunto si hay alguna solución a esto, para poder canalizar la salida de mi quickedit
función. La alternativa subóptima es iniciar un editor separado, digamos texto sublime, pero realmente quiero permanecer en la terminal.
:w !pandoc -o file.pdf
? (Nota: el espacio entrew
y!
es esencial.)mktemp
lugar de reinventarlo de manera insegura.Respuestas:
vipe
es un programa para editar tuberías:Obtiene un editor con la salida completa de
command1
, y cuando sale, el contenido se pasa acommand2
través de la tubería.En este caso, no hay
command1
. Entonces, podrías hacer:O:
vipe
recoge las variablesEDITOR
yVISUAL
, por lo que puede usarlas para abrir Vim.Si no lo tiene instalado,
vipe
está disponible en elmoreutils
paquete;sudo apt-get install moreutils
, o el equivalente de tu sabor.fuente
moreutils
está disponible en Homebrew.moreutils
está disponible para su instalación a través de pkg (8) .Puedes hacer esto desde Vim:
O incluso escriba el búfer en una tubería compleja:
Y luego puede salir de Vim sin guardar:
Sin embargo, considerando su caso de uso específico, probablemente haya una mejor solución al usarlo
vi
como su editor de línea de comandos. Suponiendo que usebash
:Esto establece sus combinaciones de teclas en
vi
. Así que usted puede editar sus comandos a la derecha en la línea de comandos básicosvi
de configuración de teclas pulsando<Esc>
y escribiendovi
comandos comox
,cw
, etc. (Puede volver a modo de inserción pulsandoi
).Aún mejor, y más relevante para esta pregunta, puede abrir Vim para crear su contenido de línea de comando directamente. Simplemente escriba
<Esc>v
y obtendrá un búfer de Vim vacío. Cuando guarda y sale, ese es el comando en su línea de comando y se ejecuta inmediatamente. Esto es mucho más flexible que editar directamente en la línea de comandos, ya que puede escribir un mini script completo si lo desea.Entonces, por ejemplo, si desea escribir un texto complicado y canalizarlo a Pandoc inmediatamente, puede escribir:
Luego edite el búfer Vim hasta que tenga algo como:
Luego guarde y salga (con
:x
) y todo se ejecutará como un comando de shell.También estará disponible en el historial de comandos de su shell.
fuente
EDITOR
variable de entornovim
y presionandoCtrl-X
seguidoCtrl-E
mientras edita la línea de comando.Corriendo en una tubería
Tratar:
La clave es que, para poder usar
vim
normalmente,vim
necesita stdout para ser el terminal. Lo logramos aquí con la redirección>/dev/tty
.Por razones de seguridad, pongo el archivo temporal en el directorio de inicio del usuario. Para obtener más información al respecto, consulte la pregunta 062 de las preguntas frecuentes de Greg . Esto elimina la necesidad de usar un nombre de archivo oscuro.
Ejemplo:
Cuando se
vim
abre, escriboThis function succeeded.
y guardo el archivo. El resultado en la pantalla se ve así:Aunque la salida de
quickedit
se redirige a una tubería,vim
todavía funciona normalmente porque le hemos dado acceso directo a ella/dev/tty
.Ejecutando un programa desde vim
Como mencioné en los comentarios, vim puede canalizar un archivo a un comando. Desde vim, por ejemplo, emita el comando
:w !pandoc -o file.pdf
(Nota: el espacio entre w y! Es esencial).fuente
trap '...' exit
falla perotrap '...' EXIT
parece funcionar. No sé mucho sobre la captura, pero mi enfoque general para los archivos temporales es usarmktmp [--suffix=...]
. Además, sevim <outfile> -c '...' >/dev/tty
ejecuta de manera normal hasta que se carga el archivo, luego ejecuta la cadena de comandos dada, incluso:wq
si desea omitir la fase de edición. También lo uséset | grep -a EXIT
y lo encontrésignals=(EXIT ... DEBUG)
.Asegúrese de que
vim
esté configurado como su editor predeterminado (por ejemplo,export EDITOR=vim
en su.bash_profile
o.bashrc
. Luego, en cualquier solicitud, puede escribir Ctrl- Xseguido de Ctrl- E. Esto abrirá su línea de comando actual en su editor configurado (por ejemplovim
). Realice sus ediciones, guarde y salga y el comando se ejecutará como si lo hubiera escrito en la línea de comando, incluidas las tuberías y similares.fuente