Cosa fa CTRL + 4 (e CTRL + \) in bash?


22

Ho appena scoperto per caso che CTRL+ 4 chiude i programmi leggendo l' stdininput dalla riga di comando.

Ecco come appare quando digito CTRL+ 4o CTRL+ / nella lettura dei programmistdin

$ cat
wefwef
wefwef
^\Quit
$ bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
^\Quit
$

Vengo ^\Quitvisualizzato e quindi il programma si chiude. Qual è la differenza rispetto all'utilizzo ^Co ^D? Cosa fa ^\Quit?

Modifica : ho scoperto che CTRL+ \fa la stessa cosa.

Risposte:


37

Ctrl + 4 invia ^ \

I terminali inviano caratteri (o più precisamente byte), non chiavi. Quando viene premuto un tasto che rappresenta un carattere stampabile, il terminale invia quel carattere all'applicazione. La maggior parte dei tasti funzione sono codificati come sequenze di escape: sequenze di caratteri che iniziano con il numero di carattere 27. Alcuni tasti della forma Ctrl+ charactere alcuni tasti funzione vengono inviati come caratteri di controllo - nel set di caratteri ASCII , che tutti i computer moderni utilizzare come base (Unicode, ISO latino- n, ecc. sono tutti superset di ASCII), 33 caratteri sono caratteri di controllo: caratteri da 0 a 31 e 127. I caratteri di controllo non sono stampabili, ma intendono avere un effetto nelle applicazioni; per esempio il carattere 10, che è Control-J (comunemente scritto ^ J), è un carattere di nuova riga, quindi quando un terminale visualizza quel carattere, sposta il cursore sulla riga successiva, anziché visualizzare un glifo. Il carattere di escape stesso è un carattere di controllo, ^ [(valore 27).

Non ci sono abbastanza personaggi di controllo per coprire tutti i Ctrl+ charactertasti. Solo le lettere e i caratteri @[\]^_?hanno un carattere di controllo corrispondente. Quando premi Ctrl+ 4o Ctrl+ $(che presumo sia Ctrl+ Shift+ 4), il terminale deve scegliere qualcosa da inviare. A seconda del terminale e della sua configurazione, ci sono diverse possibilità comuni:

  • Il terminale ignora il Ctrlmodificatore e invia il carattere 4o $.
  • Il terminale invia una sequenza di escape che codifica il tasto esatto e i modificatori che sono stati premuti.
  • Il terminale invia qualche altro carattere di controllo.

Molti terminali inviano caratteri di controllo per alcuni tasti nella riga delle cifre:

  • Ctrl+ 2→ ^ @
  • Ctrl+ 3→ ^ [
  • Ctrl+ 4→ ^ \
  • Ctrl+ 5→ ^]
  • Ctrl+ 6→ ^^
  • Ctrl+ 7→ ^ _
  • Ctrl+ 8→ ^?

Non so dove sia nata questa particolare convenzione.

Ctrl+ |invia lo stesso carattere perché è Ctrl+ Shift+ \e il terminale invia ^ \ indipendentemente dalla pressione del tasto Maiusc.

^ \ esce

Il terminale stesso (più precisamente, il supporto generico del terminale nel kernel) interpreta in modo speciale alcuni caratteri di controllo. Questa interpretazione può essere configurata per mappare caratteri diversi o disattivata da applicazioni che vogliono elaborare i caratteri da soli. Una tale interpretazione ben nota è che ^ M, il carattere inviato dal Returntasto, invia la linea corrente all'applicazione, se il terminale è in modalità di cottura , in cui le applicazioni ricevono input riga per riga.

Alcuni caratteri inviano segnali in primo piano all'applicazione. ^ C invia il segnale di interruzione (SIGINT), che convenzionale dice all'applicazione di interrompere ciò che sta facendo e di leggere il prossimo comando dell'utente. Le applicazioni non interattive di solito escono. ^ \ invia il segnale di uscita (SIGQUIT), che in modo convenzionale dice all'applicazione di uscire il prima possibile senza salvare nulla; molte applicazioni non sovrascrivono il comportamento predefinito, ovvero uccidere immediatamente l'applicazione¹. Pertanto, quando si preme Ctrl+ 4(o qualsiasi cosa che invii il carattere ^ \) in cato bc, nessuna delle quali ignora il comportamento predefinito, l'applicazione viene interrotta.

Il terminale stesso stampa la ^\parte del messaggio: è una rappresentazione visiva del personaggio che hai digitato, e il terminale è in modalità di cottura e con l'eco attivata (i caratteri vengono visualizzati dal terminale non appena li digiti, al contrario di modalità non eco in cui i caratteri vengono inviati solo all'applicazione, che può o meno scegliere di visualizzarli). La Quitparte proviene da bash: nota che il suo processo figlio è morto a causa di un segnale di uscita, e questo è il suo modo di farti sapere.

Le shell gestiscono tutti i segnali comuni, quindi se si digita ^ \ in una shell, non si uccide la sessione, si ottiene semplicemente un nuovo prompt, come ^ C.

Puoi giocare con le impostazioni del terminale con il sttycomando.

¹ E tradizionalmente genera un dump core , ma oggigiorno molti sistemi lo disabilitano di default.


SIGINT uccide il gruppo di processi in primo piano e SIGQUIT lo uccide con un core dump. Entrambi i segnali possono essere gestiti. Non sono sicuro di cosa intendi leggendo il prossimo comando . I sistemi non disabilitano i core dump se non impostando il limite iniziale di coredumpsize su 0 (non quello difficile, in genere sei libero di aumentarlo).
Stéphane Chazelas,

@ StéphaneChazelas In un programma che esegue le interazioni dell'utente, la solita semantica di SIGINT è di annullare il comando utente corrente e consentire all'utente di interagire con il programma, vale a dire di tornare al ciclo di comandi principale. D'altra parte non ricordo di aver visto un programma in cui SIGQUIT non si chiudesse (escludendo i bug nel gestore del segnale). In effetti, il modo in cui molti sistemi disabilitano i dump principali per impostazione predefinita consiste nell'impostare il limite soft della dimensione del dump principale su 0, lasciando gli utenti liberi di modificare questa impostazione predefinita se lo desiderano.
Gilles 'SO- smetti di essere malvagio' il

Questa è l'eccezione. SIGINT uccide l'attività attualmente in esecuzione. Solo poche applicazioni lo estenderebbero per uccidere il loro compito "in primo piano". Devi pensare a lesso vim. Nota che in cmd | less, CTRL-Cgeneralmente uccide cmd(mentre lessè gestito per annullare l'azione corrente (come una ricerca)) (continua)
Stéphane Chazelas

Trovo la formulazione della tua risposta confusa al riguardo. Il fatto che SIGQUIT non sia generalmente gestito è che non viene utilizzato allo stesso modo. Premi CTRL-C per interrompere ciò che stai facendo. Utilizzerai `CTRL- \` solo occasionalmente per eseguire il debug per generare un dump principale. Di solito non c'è motivo per cui un'applicazione voglia mettersi in mezzo cercando di farlo.
Stéphane Chazelas,

@ StéphaneChazelas Non solo meno e vim, la maggior parte delle applicazioni basate su terminali che leggono i comandi dell'utente. Ad esempio REPL (bash, dash, ksh, zsh, python, irb, fsharpi, Mathematica, ...). Non è raro. Il tuo primo commento obietta a dipingere SIGINT e SIGQUIT come troppo diversi e il tuo ultimo commento obietta a dipingere SIGINT e SIGQUIT come troppo simili, il che mi lascia perplesso su ciò che stai guidando.
Gilles 'SO- smetti di essere malvagio' il

7

Oltre alla risposta di Gilles, vorrei aggiungere che puoi sempre inserire caratteri non stampabili in bash con Ctrl-v+ key( Ctrl-v+ Ctrl+4in questo caso) e controllare il codice carattere con

$ printf '^\' | od -An -tu    # input ^\ as C-v C-4
28

ottieni il codice decimale del carattere, che come puoi verificare man asciicorrisponde al file separator (FS) .


Quindi cosa fanno ctrl + v? Sono abituato a essere "incolla appunti".
JDługosz,

2
@ JDługosz: Ctrl-V dice al terminale di non interpretare il seguente carattere. È un fatto spiacevole che le combinazioni di tasti della GUI abbiano preso il controllo di quei caratteri di controllo, causando inutili confusioni. In passato Linux usava Alt- [Key] per le chiavi della GUI (ad esempio Alt-C / Alt / V per copia / incolla), ma poi la gente ovviamente pensava che fare lo stesso di Windows fosse più importante; nel frattempo gli utenti Mac non hanno ancora problemi a usare il tasto Comando invece del tasto Ctrl per quelle operazioni.
Celtschk,

Il comando (più breve) è printf '%d\n' '"^\':?
Isacco,
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.