Ho ricevuto l'errore "tubo rotto" da Xcode una volta troppe. Ora sono curioso di sapere esattamente cos'è una pipa.
Qual è il concetto di "tubo" e come può essere "rotto"?
Ho ricevuto l'errore "tubo rotto" da Xcode una volta troppe. Ora sono curioso di sapere esattamente cos'è una pipa.
Qual è il concetto di "tubo" e come può essere "rotto"?
Risposte:
Una pipe è semplicemente un meccanismo di comunicazione tra processi (IPC) utilizzato per collegare l'output standard di un processo all'input standard di un altro.
Un esempio è quando si desidera cercare in un file la parola "pax":
cat filename | grep pax
e sì, so che puoi grep
direttamente il file ma questo non spiega come funziona, vero?
Ciò collega l'output standard del cat
comando all'input standard del grep
comando. cat
invia il contenuto del file al suo output standard e grep
legge il suo file (in questo caso) dal suo input standard. Collegando i processi insieme in questo modo, è possibile creare i propri strumenti costituiti da un numero qualsiasi di segmenti di tubo. Cose come:
show_users | grep pax | awk -F: '{print $4}' | tr '[a-z]' '[A-Z]' | cut -c1-20
Una pipe interrotta è quella in cui (di solito) il destinatario dei dati ha chiuso la connessione mentre il mittente sta ancora cercando di inviare roba.
Ad esempio, se si invia un file di grandi dimensioni tramite un programma cercapersone (per visualizzarlo una pagina alla volta):
cat myfile | pager
e quindi fare un CTRL-BREAK, questo potrebbe causare l' pager
arresto del processo del suo tubo di input prima che cat
abbia finito di usarlo. Questa è una possibilità per ottenere questo tubo rotto.
Da una rapida ricerca su Google , questo particolare problema sembra essere correlato a distribuzioni ad hoc e le soluzioni fornite in genere includono l'uscita dalla maggior parte del software e il riavvio della maggior parte dei dispositivi.
Questo è probabilmente abbastanza grave da segnalare il problema ad Apple. Più sviluppatori si lamentano, più è probabile che venga fatto qualcosa per risolverlo.
pr -e4 -n ten-thousand-lines.c | sed 10q
finisce con un tubo rotto. Se sia pr
fastidioso dirti che ha ricevuto il segnale SIGPIPE è un'altra cosa; potrebbe semplicemente uscire come risultato del segnale (generando uno stato di uscita diverso da zero).
Il |
personaggio è spesso chiamato pipe. Nelle varie shell UNIX (di cui sono a conoscenza) può essere utilizzato per reindirizzare l'output di un comando all'input di un altro.
cat myfile.txt | head
Il head
comando mostra solo le prime righe del suo input. A quel punto, chiude il suo input. Ciò pone un problema per il comando che stava generando l'input. Dove scrive? Ogni volta che abbiamo questa situazione, o la situazione in cui il processo di scrittura termina prima che il lettore sia finito, si chiama "tubo rotto".
Per evitare che il cat
comando indugi per sempre, lo standard UNIX definisce un segnale speciale ( SIGPIPE , segnale 13 ) al quale invia cat
. L'azione predefinita per questo segnale è quella di cat
terminare il processo, il che rende piacevole la fine.
Sembra che l'applicazione che stai utilizzando abbia installato un gestore di segnali per tutti i segnali, incluso SIGPIPE, che crea il piccolo messaggio popup che vedi.
Questo errore sembra emergere abbastanza spesso. /programming/490366/ad-hoc-deployment-issue-putpkt-write-failed-broken-pipe è "... un errore interno nella capacità di Xcode di comunicare con il tuo telefono. significa che hai fatto qualcosa di sbagliato, è un bug nel sistema di sviluppo "
Una pipe è un meccanismo IPC su sistemi Unix. Una pipe ha due estremità, una fine di lettura e una di scrittura. I dati scritti nell'estremità di scrittura possono essere letti dall'estremità di lettura ed escono nell'ordine in cui sono stati scritti.
Nel mondo della riga di comando di Unix, le pipe sono un modo molto comune di collegare programmi per svolgere un lavoro. Ad esempio sed 's/foo/bar/g' fred.txt | grep -e 'bar.*baz'
, leggerà nel file fred.txt
sostituire tutte le istanze della stringa foo
con la stringa, bar
quindi cerca nel risultato le righe che contengono bar
seguite da un numero di caratteri, quindi baz
.
Questo, ovviamente, non sembra terribilmente utile. Ma sono sicuro che se ci pensi, puoi vedere come potresti essere in grado di metterlo a tutti i tipi di usi interessanti, specialmente una volta che hai programmi simili awk
o perl
a tua disposizione.
Il sistema di tubazioni ha fatto parte di Unix sin dall'inizio. E se un processo nella tua pipeline termina, di solito vuoi che tutti i programmi nella pipeline terminino. Ciò significa che, per impostazione predefinita, un processo che scrive in una pipe in cui il processo alla fine della lettura è scomparso riceverà un SIGPIPE
segnale. E se ha bloccato quel segnale, write
fallirà comunque con un tipo speciale di errore che indica che il tubo si è "rotto".
La gestione predefinita di SIGPIPE
uccide il processo che lo riceve. E se non è la 'testa' della conduttura, l'intera SIGPIPE
cosa si propaga di nuovo sulla catena.
Ciò di cui Xcode si lamenta è che ha avviato un sottoprogramma per fare qualcosa con una pipe che lo conduce, e quel sottoprogramma è morto inaspettatamente lasciando la pipe rotta.
Una pipe “rotta” è una in cui un'estremità è stata close()
'd' e l'altra viene letta o scritta. Ad esempio, nel seguente comando shell:
cat foo | less
Il cat
processo contiene l'estremità di scrittura della pipe e il less
processo di lettura. Se il processo del lettore chiude il tubo, il tubo viene rotto (e quindi inutile); il processo di scrittura riceverà l'errore "tubo rotto" dal sistema operativo.
cat
ovviamente lo farà non appena sarà finito), il lettore vedrà solo una normale fine del file.