In che modo "cp" gestisce i file aperti?


15

Sto avendo due directory separate. L'utente carica un file nel primo. C'è un cronjob in esecuzione in background che copia i file ogni 5 minuti nella seconda directory.

Cosa succede se l'utente non ha completato il suo caricamento e cronjob copia i file? Si noti che le due directory sono di proprietà di utenti diversi, il cronjob viene eseguito come root.


leggi questo post per vedere cosa succede in questo caso: unix.stackexchange.com/questions/49299/…
Serge

Grazie, buon post che hai scritto. Ma la mia domanda riguardava più i cp, non la gestione dei file linux in generale. Forse però cp controlla se il file è ancora aperto e aspetta fino alla sua chiusura o qualcosa del genere.
Stuffy

No. cpnon attenderà fino al completo caricamento del file. Poiché prevediamo che la velocità di trasferimento in rete sia inferiore alla semplice copia del file da una posizione a un'altra all'interno dello stesso host, ad un certo punto cpraggiungerà l'attuale fine del file e interromperà la copia. La soluzione al tuo problema potrebbe essere semplice: in primo luogo l'utente carica il file con un nome di file appositamente modificato (ad esempio anteposto con .(punto carattere). Al termine del trasferimento, l'utente lo rinomina con il nome originale. Quindi il processo cron appare solo per i file che non iniziano con ..
Serge

Risposte:


17

cpnon conosce file aperti. Quindi, se il primo utente carica file di grandi dimensioni e cronjob (o qualsiasi altro processo) inizia a copiare questo file, verrà copiato solo quanto è stato già scritto. Puoi pensarci in questo modo - cpfa una copia di ciò che è attualmente sul disco, indipendentemente dal fatto che il file sia completo. Altrimenti, ad esempio, non è possibile copiare file di registro.


Grazie, questo è quello che volevo sapere! C'è un modo semplice per evitarlo? Ho controllato la pagina man di cp ma non ho trovato nulla di utile.
Stuffy

Per fare esattamente cosa? Per copiare tutti i file tranne quelli aperti? Non credo che ci sia un modo semplice per farlo (oltre a scrivere il tuo script che utilizza fuser+ cp. Tale copia sarebbe davvero molto inaffidabile. Non copierà alcun file aperto nell'editor di testo, ad esempio.
Krzysztof Adamski,

@Stuffy, forse nel tuo cronjob potresti elencare i file aperti con lsof? L'output di questo è pensato per essere facile da elaborare. È possibile filtrare i file che vengono aperti (ad esempio da un'istanza di cp) per la scrittura.
Wojtek Rzepala,

@WojtekRzepala, darò un'occhiata a questo, grazie. Forse scriverò una piccola sceneggiatura che viene eseguita dal cronjob
Stuffy,

@Stuffy: tieni presente che potrebbe non essere davvero affidabile se non è gestito dall'utente root (lo stesso problema è fuserovviamente con) poiché questo strumento potrebbe non mostrare tutti i file.
Krzysztof Adamski,

7

cpnon sa quali altri programmi potrebbero avere i file aperti. Non c'è magia dentro cp. La progettazione di unix evita intenzionalmente di mettere qualsiasi tipo di blocco sui file a meno che non ci sia una ragione convincente (significato convincente che il kernel ne ha bisogno). Su questo argomento, vedere Il reindirizzamento dell'output su un file applica un blocco sul file?

Tali situazioni, in cui un file è prodotto da un produttore e, una volta completato, consumato da un consumatore, sono comuni. Il modo abituale di gestirlo è fare in modo che il produttore scriva un file temporaneo che il consumatore non cercherà, quindi una volta terminato il produttore, spostare il file in un punto in cui il consumatore lo troverà. Lo spostamento di un file (sullo stesso filesystem) è un'operazione atomica: ad un certo punto, per il consumatore, il file cambia da non essere lì a essere lì.

Quindi organizza che il tuo processo di caricamento trasferisca i file in una directory diversa al termine del caricamento. Punta il cron job su questa diversa directory.


6

Sembra che tu voglia fare un lavoro di sincronizzazione dir.

Perché l' opzione -u, --update dicp

copia solo quando il file SOURCE è più recente del file di destinazione o quando manca il file di destinazione

Quindi puoi aggiungere un cronjob come quello cp -auv SOURCEDIR/* DESTDIRche copierà quei file il cui tempo di modifica è cambiato. Ciò significa DESTDIRche alla fine otterrà la copia completa al termine del caricamento.

rsyncpuò fare lo stesso lavoro. ad es rsync -av SOURCEDIR/ DESTDIR.

Sebbene sia applicata un'opzione, alcuni attributi specifici (ad es. Proprietà) possono essere conservati solo dal superutente.

Vedi man cp, man rsyncper i dettagli.


Basta fare attenzione a fare affidamento su voci recenti nella cartella di destinazione --- potrebbero non essere file completi.
dubiousjim,
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.