¿Por qué no se puede salir de ed con Cc?


20

El programa ed, un editor de texto mínimo, no se puede salir mediante el envío de una interrupción a través del uso Ctrl- C"?", En lugar de imprimir el mensaje de error a la consola ¿Por qué no edsolo sale cuando recibe la interrupción? Seguramente no hay ninguna razón por la cual un mensaje de error críptico sea más útil aquí que simplemente salir. Este comportamiento lleva a muchos usuarios nuevos al siguiente tipo de interacción:

$ ed
hello
?
help
?
exit
?
quit
?
^C
?
^C
?
?
?
^D
$ su
# rm -f /bin/ed

Un desperdicio tan trágico, fácilmente evitable si edsimplemente aceptara ser interrumpido.

Otro programa obstinado que exhibe un comportamiento similar es el lessque tampoco parece tener muchas razones para ignorar C-c. ¿Por qué estos programas simplemente no dan una pista?


44
Las aplicaciones interactivas no son lo mismo que las no interactivas. El comportamiento Ctrl-C al que está acostumbrado es el predeterminado para los no interactivos. Los interactivos pueden anular el comportamiento de Ctrl-C para sus propios fines.
jw013

44
Además, no estoy seguro si broma
jw013

@ jw013 Sí, la "sesión típica" fue una broma (no pude encontrarla por alguna razón) pero mi pregunta es seria. Lo que no entiendo es por qué estas aplicaciones eligen anular el comportamiento de Ctrl-C si en realidad no proporciona nada útil.
Lily Chung

1
Dado que esta pregunta aparece como una de las principales respuestas de búsqueda de Google a "cómo salir de ed", me gustaría agregar aquí que es solo 'q' seguido de un retorno. Muchos bothanos murieron para traernos esta información.
Dmitri

Respuestas:


19

Ctrl+ Cenvía SIGINT . La acción convencional para SIGINT es regresar al ciclo de nivel superior de un programa, cancelando el comando actual y entrando en un modo en el que el programa espera el siguiente comando. Se supone que solo los programas no interactivos deben morir de SIGINT.

Por lo tanto, es natural que Ctrl+ Cno mate a ed, sino que haga que regrese a su ciclo de nivel superior. Ctrl+ Caborta la línea de entrada actual y vuelve a la línea de comandos ed.

Lo mismo ocurre con menos: Ctrl+ Cinterrumpe el comando actual y lo regresa a su símbolo del sistema.

Por razones históricas, ed ignora SIGQUIT ( Ctrl+ \). Las aplicaciones normales no deberían captar esta señal y permitir que se terminen, con un volcado de núcleo si está habilitado.


@Kzqai No, las aplicaciones normales no deberían atrapar a SIGQUIT, es una salida de emergencia.
Gilles 'SO- deja de ser malvado'

Ah, te tengo. Muy bien, retraído.
Kzqai

18

El código fuente de Unix V7ed(1) es un programa primitivo de 1.762 líneas C con solo unos pocos comentarios, uno de los cuales es este comentario de encabezado muy esclarecedor:

/*
 * Editor
 */

Dado que el código fuente en sí no proporciona ninguna justificación, solo lo obtendrá del autor del programa.

edoriginalmente fue escrito por Ken Thompson en el ensamblaje PDP-11 , pero en realidad necesitarías hablar con quien lo haya portado a C. Ese podría haber sido Dennis Ritchie , ya que creó C para Unix, y fue uno de los muchos que usaron C hacer que Unix sea portátil para máquinas que no sean PDP. Sin embargo, el Dr. Ritchie ya no está cerca para responder esas preguntas.

Mi lectura del código sugiere que se ha hecho para tratar de preservar el contenido de la en-core copia del documento editado. Notarás que otros editores de texto tampoco mueren Ctrl-C.

edEsto es lo que hace en Ctrl-C:

onintr()
{
    signal(SIGINT, onintr);
    putchr('\n');
    lastc = '\n';
    error(Q);
}

(Sí, K&R C. No necesitamos especificadores de tipo de retorno de steenkin ni declaraciones de parámetros).

Traducido al inglés ed,:

  1. Vuelve a registrar el controlador de señal.

    (Unix no recibió señales de reinicio automático hasta 4.3BSD , a mediados de la década de 1980).

  2. Escribe una nueva línea y recuerda que lo hizo a través de la variable global lastc.

    ( ed.ctiene alrededor de sesenta variables globales).

  3. Llama a la error()función, que famoso no hace más que imprimir ?, desde la perspectiva del usuario.

En otras palabras, dice: "Realmente no quisiste hacer eso, ¿verdad?"


2
También vale la pena señalar que muchos editores de texto no salen en Control-C. Vim tampoco lo hace. Tampoco nano. Tampoco creo que emacs lo haga, pero no lo tengo instalado para probar.
derobert

3
@derobert Vi trata Ctrl + C de la manera Unix: vuelve al nivel superior. Emacs tiene sus propias combinaciones de teclas, debido a sus orígenes no Unix; el equivalente de Emacs de Ctrl + C de Unix es Ctrl + G (el carácter de la campana - toque la campana en la computadora para interrumpirlo)
Gilles 'SO- deja de ser malvado'

@derobert: punto justo. He agregado esto a la respuesta.
Warren Young

2
@Gilles: Uno de los efectos secundarios de la llamada error(s)en ed.ces volver al bucle de procesamiento principal. Lo hace con una longjmp()llamada. estremecimiento
Warren Young

1
Gracias por los detalles y la lección de historia. ¡Esta fue una gran lectura!
alichaudry

7

ed, como otros programas interactivos, use Ctrl+ Cpara interrumpir las tareas del programa en sí.
Esto es muy similar al caso normal, donde interrumpe una tarea que se ejecuta en el shell: un comando.

Desde la perspectiva del usuario, ambas variantes son muy similares. El manejo de la señal es diferente: en el caso habitual, la señal SIGINTse envía al proceso en primer plano, a un comando en ejecución, y el comando la maneja al salir.
En el caso de ed, la señal se envía al proceso de primer plano, la edinstancia. Si hay una tarea ejecutándose ed, se interrumpe y se muestra el mensaje. Si no hay ninguna tarea en ejecución, no se cambia nada.

Tenga en cuenta que un shell tampoco sale en Ctrl+ C, al igual que ed. Y que sí sale en Ctrl+ D. De nuevo, al igual queed


3

Hay tres señales que edle importan:

  1. INT
  2. HUP
  3. QUIT

La especificación POSIX deed dice lo siguiente acerca de estos:

SIGINT

La edutilidad interrumpirá su actividad actual, escribirá la cadena ?\nen la salida estándar y volverá al modo de comando (consulte la sección DESCRIPCIÓN EXTENDIDA).

SIGHUP

Si el búfer no está vacío y ha cambiado desde la última escritura, la edutilidad intentará escribir una copia del búfer en un archivo. Primero, ed.hupse utilizará el archivo nombrado en el directorio actual; si eso falla, se utilizará el archivo nombrado ed.hupen el directorio nombrado por la HOMEvariable de entorno. En cualquier caso, la edutilidad se cerrará sin escribir el archivo en la ruta recordada actualmente y sin volver al modo de comando.

SIGQUIT

La edutilidad ignorará este evento.

Entonces, cualquier implementación edque esté utilizando, se ajusta a la especificación POSIX con respecto a la INTseñal (que es lo que Ctrl+Cenvía).

En este sentido, el editor se comporta como un shell interactivo, que tampoco termina al recibir la INTseñal. Otros editores, como viy nanohace lo mismo.


1
Algunas implementaciones de programas contradicen deliberadamente POSIX, por lo que podría ser útil explicar la justificación del estándar / el costo de romperlo en este caso. stackoverflow.com/questions/38605463/…
sourcejedi

1
@sourcejedi El estándar no dice nada sobre las señales en su justificación. No he encontrado ninguna razón que diga nada acerca de por qué se sigue el estándar en las fuentes edque tengo disponibles. Se comporta de manera similar al shell, que tampoco termina al recibir la INTseñal.
Kusalananda
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.