2009-11-06 29 views
17

Me gustaría que mi guión tcsh para poner en marcha un editor (por ejemplo, vi, emacs):¿Cómo ejecuto un editor desde un script de shell?

#!/bin/tcsh 
vi my_file 

Esto pone en marcha VI con mi_archivo pero primero muestra una advertencia "Vim: Advertencia: La salida no es un terminal" y mis teclas no aparecen en la pantalla. Después de matar a vi, mi ventana de terminal está en mal estado (sin líneas nuevas), que requiere un "reinicio". Intenté "emacs -nw", "xemacs -nw" y pico con resultados similares. "xemacs" funciona pero inicia una ventana separada. Quiero reutilizar la misma ventana de terminal.

¿Hay una manera de lanzar un editor de un guión para que se reutiliza la misma ventana de terminal?

+0

Normalmente hago exactamente lo que haces y funciona bien para mí. Pero mi caparazón es bash. Este tipo de cosas también funciona bien bajo sh. ¿Puede hacer un "que vi" para averiguar si se está llamando a algo que no sea vi? Y ... ¿en qué tipo de entorno de sistema operativo se está ejecutando? –

+1

Con bash y vim puedes hacer vi my_file desde el script. No sé por qué tendrías que hacer algo especial. –

+0

¿Está intentando que vim lea un ARCHIVO o los contenidos de VARIABLE? – matpie

Respuesta

16

¡Respondí mi propia pregunta! Usted tiene que redirigir la entrada del terminal y de salida:

#!/bin/tcsh 
vi my_file < `tty` > `tty` 
+3

pero ... pero ... pero ... redirigir desde dónde? Todavía es un misterio para mí por qué deberías necesitar hacer esto. –

+0

Estoy tratando de hacer eso con vim pero solo obtengo '\ 'tty \': redirección ambigua ' –

+3

Resulta que' \ 'tty \' 'estaba expandiéndose a" no un tty "dentro de mi script. Acabo de usar '/ dev/tty', pero me pregunto qué tan portátil podría ser ... –

2

yo era capaz de conseguir el comportamiento deseado bajo bash + Cygwin + Terminator:

#!/bin/bash 
vim foo 

Ejecutar la secuencia de comandos, cargas vim, ningún mensaje de error, se comporta como normal. Sin embargo, existen docenas de variaciones entre nuestras configuraciones, por lo que no puedo aventurarme a adivinar cuál es la diferencia. Tengo curiosidad de lo que es, pero lo pusiste en funcionamiento, que es la parte importante.

11

La razón por la que aparece el error es que cuando inicia un shell en su entorno, se inicia en una subshell que tiene STDIN y STDOUT no conectados a un TTY, probablemente porque se trata de algo así como una tubería. Cuando redirige, está abriendo una nueva conexión directamente al dispositivo. Así, por ejemplo, la línea de comandos convierte

$ vi < `tty` > `tty` 

en

$ vi </dev/ttys000> /dev/ttys000 

así que en realidad no estás usando tu viejo STDIN/STDOUT, va a crear dos nuevos archivos y asignándolos a el STDIN/STDOUT de tu vi.

Ahora, nos dicen lo que está haciendo con esto y te diremos cómo evitar este kludge.

+0

No estoy creando nuevos archivos. Estoy redireccionando el archivo de mi dispositivo terminal (tty le dice qué archivo es), que está asociado con mi ventana de terminal y existía antes de ejecutar mi script, al STDIN/STDOUT de vi. Creé un script que ajusta "cvs commit" y realiza muchas comprobaciones adicionales (por ejemplo, ejecuta nuestro banco de pruebas) antes de confirmar el check-in. Esto a veces se llama un "check-in cerrado". Por razones que no entraré, no puedo usar el gancho pre-commit estándar de CVS. Intento emular cómo "cvs commit" inicia un editor cuando no se especifica un mensaje de confirmación en la línea de comando. –

2

Absolutamente. :-)

Escriba su guión y tener que llamar a la variable de entorno EDITOR, que se le han establecido en "emacsclient". A continuación, inicie Emacs, ejecute M-x server-start, cambie a un búfer de shell (M-x shell) y ejecute su script. Emacsclient mostrará el elemento que se va a editar y C-x # actuará como un comando "hecho" y lo llevará de vuelta a su secuencia de comandos con las ediciones completadas o canceladas, según lo desee.

Disfrútalo.

Editar: Quise agregar que Emacs ES hoy en día mi programa de terminal. Tengo docenas de búferes de shell y nunca tengo que preocuparme por perder resultados y puedo usar toda la potencia de Emacs para manipular y analizar la salida del terminal. Y los scripts de Emacs generan entradas para los shells. Impresionante en realidad. Por ejemplo, ver la salida de Tomcat desplazarse por un búfer de shell mientras se editan las fuentes o procesar el correo o hacer casi cualquier cosa de Emacs es muy conveniente. Cuando aparece un rastro de la pila Tomcat, puedo responder rápidamente.

3

Indica tu terminal de tty a una variable, y luego vuelven a dirigir el editor de E/S a través de esa variable.

En la secuencia de comandos:

#!/bin/sh 

ls | while read a; do vi $a < $MYTTY >$MYTTY; done 

y luego ejecutar el script con:

$ MYTTY=`tty` ./myscript >/tmp/log 
2

tenía el mismo problema con 'pinfo' en un script de shell 'mientras que' bucle. La línea puede ser utilizado en el guión, que utiliza 'ps' para encontrar el TTY del número actual proceso, "$$", y las tiendas que TTY en $ KEY_TTY:

KEY_TTY=/dev/`ps | grep $$ | tr -s '[:blank:]' | cut -d " " -f 3` 

Más adelante en el guión, simplemente llamar al TTY proggie-solamente, con $ KEY_TTY como entrada, en mi caso fue:

pinfo -m $s $page < $KEY_TTY 

Para 'vi' sería:

vi $a < $KEY_TTY > $KEY_TTY 

la ventaja es que el script como todo todavía puede aceptar entrada STDIN, y 'vi' (o lo que sea) debería funcionar bien - - sin tener que recordar establecer cualquier variable ambiental antes de ejecutar el script.

6

Yo quería hacer algo similar. Quería un alias que encontraría el último archivo en el que estaba trabajando y abrirlo en vi (1) para editarlo. De todos modos, no podía encontrar la manera de hacerlo como un alias de lectura (en tsch) por lo que acaba de crear una secuencia de comandos shell fea (CSH porque soy de edad) en su lugar:

#!/bin/csh 

set DIR = "~/www/TooMuchRock/shows/" 

set file = $DIR`ls -t $DIR | head -1` 
set tty = `tty` 

vi $file <$tty >$tty 

(1) Kraftwerk: bin> que vi vi: aliased/usr/local/bin/vim -u ~/.exrc

Cuestiones relacionadas