Ctrl + D para finalizar la entrada de línea de terminal

21

Si lo hago

$ cat > file.txt

texto Ctrl- DCtrl-D

Pregunta 1: Si no lo presione ENTRAR, ¿por qué tengo que pulse Ctrl- Ddos veces?

Si lo hago

$ cat > file.txt

pa bam pshhh Ctrl-Z

[2]+  Stopped         cat > file.txt
$ cat file.txt
$ cat > file.txt

pa bam pshhh

Ctrl-Z

[2]+  Stopped         cat > file.txt
$ cat file.txt
pa bam pshhh

¿Por qué es la segunda vez que el archivo con 1 línea?

niebla
fuente
2
Este hilo bajo el paraguas de sitios de intercambio de pila tiene la respuesta que está buscando: stackoverflow.com/questions/7369170/… . Espero eso ayude.
Sí, aunque no esté relacionado con Python, mi pregunta es un duplicado.
niebla
Cuando escribe ctrl-z, ¿realmente está recibiendo un nuevo indicador de shell o también está recibiendo un mensaje acerca de catser detenido?
Mark Plotnick
Actualizaré la pregunta
niebla el

Respuestas:

30

En Unix, la mayoría de los objetos que puede leer y escribir (archivos normales, tuberías, terminales, unidades de disco sin formato) están hechos para parecerse a los archivos.

Un programa como se catlee desde su entrada estándar de esta manera:

n = read(0, buffer, 512);

que pide 512 bytes. nes el número de bytes realmente leídos, o -1 si hay un error.

Si hiciera esto repetidamente con un archivo ordinario, obtendría un montón de lecturas de 512 bytes, luego una lectura algo más corta al final del archivo, luego 0 si intenta leer más allá del final del archivo. Entonces, catse ejecutará hasta que nsea ​​<= 0.

Leer desde una terminal es ligeramente diferente. Después de escribir una línea, terminada por la Entertecla, readdevuelve solo esa línea.

Hay algunos caracteres especiales que puede escribir. Uno es Ctrl-D. Cuando escribe esto, el sistema operativo envía toda la línea actual que ha escrito (pero no la Ctrl-Dpropia) al programa que realiza la lectura. Y aquí está lo fortuito: si Ctrl-Des el primer carácter de la línea, el programa recibe una línea de longitud 0, tal como vería el programa si llegara al final de un archivo ordinario. cat no necesita hacer nada diferente , ya sea leyendo un archivo ordinario o un terminal.

Otro personaje especial es Ctrl-Z. Cuando lo escribe, en cualquier lugar de una línea, el sistema operativo descarta todo lo que ha escrito hasta ese punto y envía una señal SIGTSTP al programa, que normalmente lo detiene (pausa) y devuelve el control al shell.

Entonces en tu ejemplo

$ cat > file.txt
pa bam pshhh<Ctrl+Z>
[2]+  Stopped         cat > file.txt

usted escribió algunos caracteres que fueron descartados, luego catfue detenido sin haber escrito nada en su archivo de salida.

$ cat > file.txt
pa bam pshhh
<Ctrl+Z>
[2]+  Stopped         cat > file.txt

escribió en una línea, que catleyó y escribió en su archivo de salida, y luego se Ctrl-Zdetuvo cat.

Mark Plotnick
fuente
1
Estas cosas solo son ciertas para los terminales de modo canónico . E incluso en ese caso se pueden cambiar.
mikeserv
@mikeserv Eso es cierto. Aquí, quería explicar exactamente lo que estaba viendo el OP. También consideré describir el modo de terminal raw / -icanon, otros caracteres especiales, cómo se pueden personalizar, cómo difieren según el sistema operativo, etc., pero no quería dar una respuesta demasiado larga.
Mark Plotnick el
¿Lo anterior implica que si la entrada no se realizara cat, que un programa que leía datos del teclado y no se detenía la primera vez que readproducía un cero podría continuar, y la cantidad de D de control requerida estaría determinada por ¿El número de ceros consecutivos que el programa requirió para decidir que se hizo?
supercat
@supercat Un programa puede seguir leyendo si lo desea. En el exeditor, si escribe un control-D como el primer carácter de una línea, el editor le muestra algunas líneas del programa en lugar de salir. (En exy vi, Control-D es un mnemotécnico para "abajo"). Y con muchos shells, si escribe Control-D pero tiene trabajos ejecutándose en segundo plano, el shell le informará de esto en lugar de salir, pero si vuelve a escribir Control-D, el shell decide que realmente desea salir de todos modos y lo haré
Mark Plotnick
@ MarkPlotnick: ¿Hay alguna forma de enviar estos hipo de byte cero a través de una tubería?
supercat
19

Eso es porque Ctrl+ Des un truco.

En el fondo, Ctrl+ D(a pesar de ser llamado el eofpersonaje ) en realidad no significa el final del archivo: significa "enviar la entrada pendiente a la aplicación ahora". Esto está realmente cerca del significado de Ctrl+ M( eol), que envía la entrada pendiente más una nueva línea.

Cuando presiona Ctrl+ Dinmediatamente después de un Ctrl+ M(es decir, al comienzo de una línea) o después de otro Ctrl+ D, la entrada pendiente está vacía. Por lo tanto, la aplicación recibe 0 bytes de entrada. En una readllamada, leer 0 bytes señala el final del archivo.


Cuando presiona Ctrl+ Z, la entrada pendiente se descarta. Por lo tanto, solo se procesa lo que ya se había enviado a la aplicación (que es cat) ingresando una nueva línea o Ctrl+ Dantes de presionar Ctrl+ Z.

Gilles 'SO- deja de ser malvado'
fuente
1
Puede encontrar más información sobre ctrl + D de una de las respuestas de Gille aquí .
Ramesh
Como dijiste, Ctrl-D no significa fin de archivo. De hecho, no significa que sea porque Ctrl-D es EOT (fin de texto).
H2ONaCl