Il reindirizzamento dell'output su un file applica un blocco sul file?


30

Se ho un comando

$ ./script >> file.log

che viene chiamato due volte, con la seconda chiamata che si verifica prima della fine della prima, cosa succede?

La prima chiamata ottiene un blocco esclusivo sul file di output? In tal caso, il secondo script non riesce quando si tenta di scrivere o la shell accetta l'output (consentendo allo script di terminare) e genera un errore?

O il file di registro viene scritto due volte?


1
Non conosco alcun sistema che blocchi il file per impostazione predefinita. Ciò che è più probabile è che i due programmi finiscano per intercalare le loro scritture, poiché entrambi sarebbero in modalità append. I risultati sarebbero piuttosto imprevedibili. Invece di "ciao mondo" potresti ottenere "hweolrllod".
jw013,

Risposte:


18

Dal momento che stai usando >>, il che significa aggiungere, ogni riga di output di ogni istanza verrà aggiunta nell'ordine in cui si è verificata.

Se le stampe in uscita di script 1\nattraverso 5\ncon un ritardo di un secondo tra ogni e esempio due si avvia 2,5 secondi più tardi si otterrà questo:

1
2
1
3
2
4
3
5
4
5

Quindi, per rispondere alla tua domanda: No.


23

I sistemi Unix in generale evitano i blocchi obbligatori. Ci sono alcuni casi in cui il kernel bloccherà un file contro le modifiche dei programmi utente, ma non se viene semplicemente scritto da un altro programma. Nessun sistema unix bloccherà un file perché un programma ci sta scrivendo.

Se vuoi che le istanze simultanee del tuo script non si calpestino sulle dita dei piedi degli altri, devi usare un meccanismo di blocco esplicito come .flock lockfile

Quando si apre un file per l'aggiunta, il che >>fa sì che ogni programma scriva sempre alla fine del file. Quindi l'output delle istanze multiple non si sovrascriverà mai a vicenda, e se si alternano per scrivere, il loro output sarà nello stesso ordine delle scritture.

La cosa brutta che potrebbe accadere è se una delle istanze scrive diversi blocchi di output e si aspetta che vengano pubblicati insieme. Tra le scritture consecutive di un'istanza, altre possono eseguire le proprie scritture. Ad esempio, se l'istanza 1 scrive foo, quindi l'istanza 2 scrive helloe solo allora l'istanza 2 scrive bar, il file conterrà foohellobar.

Un processo scrive efficacemente nel file quando chiama la writechiamata di sistema. Una chiamata a writeè atomica: ogni chiamata a writescrive una sequenza di byte che non verrà interrotta da altri programmi. Esiste spesso un limite alla quantità di dati a cui una singola chiamata writescriverà effettivamente: per dimensioni maggiori, viene scritto solo l'inizio dei dati e l'applicazione deve richiamare writenuovamente. Inoltre, molti programmi eseguono il buffering: accumulano i dati in un'area di memoria, quindi li scrivono in un blocco. Alcuni programmi scaricano il buffer di output dopo una riga completa o un'altra separazione significativa. Con tali programmi, puoi aspettarti che intere linee siano ininterrotte, purché non siano troppo lunghe (fino a pochi kilobyte; questo dipende dal sistema operativo). Se il programma non scarica in punti significativi, ma solo in base alla dimensione del buffer, potresti vedere qualcosa come 4kB da un'istanza, quindi 4kB da un'altra istanza, quindi ancora 4kB dalla prima istanza e così via.

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.