Ctrl + D per terminare l'ingresso della linea terminale


21

Se lo faccio

$ cat > file.txt

testo Ctrl- DCtrl-D

Domanda 1: se non lo faccio premere Invio, perché devo stampa Ctrl- Ddue volte?

Se lo faccio

$ 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

Perché è la seconda volta che il file con 1 riga?


2
Questo thread sotto l'ombrello dei siti stackexchange ha la risposta che stai cercando: stackoverflow.com/questions/7369170/… . Spero che sia d'aiuto.

Sì, anche se non legato a Python, la mia domanda è un duplicato.
nebbia

Quando digiti ctrl-z, ricevi davvero solo un nuovo prompt della shell o ricevi anche un messaggio catsull'arresto?
Mark Plotnick,

Aggiornerò la domanda
mist

Risposte:


30

In Unix, la maggior parte degli oggetti che è possibile leggere e scrivere - normali file, pipe, terminali, unità disco non elaborate - sono tutti realizzati per assomigliare ai file.

Un programma come catlegge dal suo input standard in questo modo:

n = read(0, buffer, 512);

che richiede 512 byte. nè il numero di byte effettivamente letti o -1 se si verifica un errore.

Se lo facessi ripetutamente con un normale file, otterrai un sacco di letture da 512 byte, quindi una lettura un po 'più breve alla fine del file, quindi 0 se provassi a leggere oltre la fine del file. Quindi, catverrà eseguito fino a quando n<= 0.

La lettura da un terminale è leggermente diversa. Dopo aver digitato una riga, terminata dalla Enterchiave, readrestituisce solo quella riga.

Ci sono alcuni caratteri speciali che puoi digitare. Uno è Ctrl-D. Durante la digitazione, il sistema operativo invia tutta la riga corrente digitata (ma non la Ctrl-Dstessa) al programma che esegue la lettura. Ed ecco la cosa fortuita: se Ctrl-Dè il primo carattere sulla linea, al programma viene inviata una linea di lunghezza 0 - proprio come il programma vedrebbe se arrivasse alla fine di un normale file. cat non deve fare nulla di diverso , sia che si tratti di leggere da un file ordinario o di un terminale.

Un altro personaggio speciale è Ctrl-Z. Quando lo digiti, ovunque in una riga, il sistema operativo scarta qualsiasi cosa tu abbia scritto fino a quel punto e invia un segnale SIGTSTP al programma, che normalmente lo ferma (mette in pausa) e restituisce il controllo alla shell.

Quindi nel tuo esempio

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

hai digitato alcuni caratteri che sono stati scartati, quindi è catstato interrotto senza aver scritto nulla nel suo file di output.

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

hai digitato in una riga, che catleggeva e scriveva nel suo file di output, e poi l' Ctrl-Zarresto cat.


1
queste cose sono vere solo per i terminali in modalità canonica . E anche in quel caso possono essere cambiati.
Mikeserv,

@mikeserv È vero. Qui, volevo spiegare esattamente cosa stava vedendo l'OP. Ho anche considerato di descrivere la modalità terminale raw / -icanon, altri caratteri speciali, come possono essere personalizzati, in che modo differiscono per sistema operativo, ecc. Ma non volevo rendere la risposta eccessivamente lunga.
Mark Plotnick,

Quanto sopra implica che se l'input non passasse cat, che un programma che leggeva i dati dalla tastiera e non si fermava la prima volta readproduceva uno zero poteva continuare, e il numero di control-D richiesti sarebbe determinato da il numero di zero consecutivi richiesti dal programma per decidere che è stato fatto?
supercat

@supercat Un programma può continuare a leggere se lo desidera. Nell'editor ex, se si digita control-D come primo carattere di una riga, l'editor mostra alcune righe del programma anziché uscire. (In exe vi, Control-D è un mnemonico per "giù"). E con molte shell, se si digita Control-D ma si hanno lavori in esecuzione in background, la shell ti informerà piuttosto che uscire, ma se si digita nuovamente Control-D, la shell decide che vuoi davvero uscire comunque e lo farà.
Mark Plotnick,

@MarkPlotnick: esiste un modo per inviare questi singhiozzi a zero byte tramite pipe?
supercat

19

Questo perché Ctrl+ Dè un hack.

In fondo, Ctrl+ D(nonostante sia chiamato il eofpersonaggio ) in realtà non significa fine del file: significa "invia subito l'input in sospeso all'applicazione". Questo è in realtà vicino al significato di Ctrl+ M( eol), che invia l'input in sospeso più una nuova riga.

Quando si preme Ctrl+ Dimmediatamente dopo un Ctrl+ M(ovvero all'inizio di una riga) o dopo un altro Ctrl+ D, l'ingresso in sospeso è vuoto. Pertanto l'applicazione riceve 0 byte di input. In una readchiamata, la lettura di 0 byte indica la fine del file.


Quando si preme Ctrl+ Z, l'input in sospeso viene eliminato. Pertanto, viene elaborato solo ciò che era già stato inviato all'applicazione (ovvero cat) immettendo una nuova riga o Ctrl+ Dprima di premere Ctrl+ Z.


1
Maggiori informazioni su ctrl + D da una delle risposte di Gille sono disponibili qui .
Ramesh,

Come hai detto, Ctrl-D non significa fine del file. In effetti, ciò non significa che sia perché Ctrl-D è EOT (fine del testo).
H2ONaCl
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.