Supponiamo che io legga (cat) un file mentre un altro processo sta riscrivendo il suo contenuto. L'output è prevedibile? Cosa succederebbe?
Supponiamo che io legga (cat) un file mentre un altro processo sta riscrivendo il suo contenuto. L'output è prevedibile? Cosa succederebbe?
Risposte:
Dipende da cosa fa lo scrittore.
Se lo scrittore sovrascrive il file esistente, il lettore vedrà il nuovo contenuto quando lo scrittore supera il lettore, se mai. Se lo scrittore e il lettore procedono a velocità variabile, il lettore può in alternativa vedere contenuti vecchi e nuovi.
Se il writer tronca il file prima che inizi a scrivere, il lettore verrà eseguito alla fine del file in quel punto.
Se il writer crea un nuovo file, quindi sposta il nuovo file sul vecchio nome, il lettore continuerà a leggere dal vecchio file. Se un file aperto viene spostato o rimosso, i processi che hanno il file aperto continuano a leggere dallo stesso file. Se il file viene rimosso, rimane effettivamente sul disco (ma senza possibilità di riaprirlo) fino a quando l'ultimo processo non lo ha chiuso.
I sistemi Unix tendono a non avere blocchi obbligatori . Se un'applicazione desidera assicurarsi che il suo componente writer e il componente reader non si pettino l'un l'altro, spetta allo sviluppatore utilizzare il blocco corretto. Ci sono alcune eccezioni in cui un file aperto dal kernel può essere protetto dalla scrittura da parte delle applicazioni dell'utente, ad esempio un'immagine del filesystem montata su loop o un eseguibile che viene eseguito su alcune varianti unix.
ftp
/ sftp
scenari? Supponiamo che un processo inizi a leggere un ftp
file trasmesso mentre un'altra versione dello stesso file lo sovrascrive a causa di una nuova trasmissione.
È una condizione di gara classica, quindi il risultato è imprevedibile per definizione.
Tra l'altro, dipende da
fopen(3)
o open(2)
modalità di scrittura,Se devi essere in grado di leggere un file mentre viene riscritto, puoi fare in modo che il writer esegua una copia temporanea del file, modificarlo e copiarlo nuovamente nel file originale. In questo modo rsync
, ad esempio. Esistono diversi modi per implementarlo, ma nessun pranzo libero. Ogni metodo ha le sue carenze e ripercussioni.
I rispondenti precedenti hanno spiegazioni più complete di così, ma ecco un trucco che funziona sicuramente anche, praticamente facendo esattamente quello che vuole:
$ tail -f <filename>
Ti mostrerà la fine del file mentre viene scritto. Comodo se si desidera reindirizzare STDERR a un file ma ancora vederlo in un'altra finestra del terminale, ad esempio.