[Linuxtrent] Re: appello agli esperti perl

  • From: Flavio Stanchina <flavio@xxxxxxxxxxxxx>
  • To: linuxtrent@xxxxxxxxxxxxx
  • Date: Mon, 27 Oct 2014 17:45:03 +0100

Michele Bert wrote:
Sto scrivendo uno script in perl che a grandi linee fa 3 semplicissime cose:
- prende un file testo codificato ebcdic, cui tutte le righe sono
lunge 79 caratteri, e privo di carattere di fine riga.
- lo converte in ascii, ed inserisce un carattere di fine riga ogli 79 caratteri
- copia/sposta il risultato in un altra directory

Per convertire da ebcdic ad ascii uso dd, mettendo l'output in pipe
con un HANDLE perl, da cui leggo 79 caratteri alla volta, che scrivo,
intervallati da uno '\n', in un file nella direcory corrente. Infine
chiamo cp oppure mv attraverso una chiamata system() per spostare il
file.

Se copio il file il risultato sembra corretto, mentre se lo sposto,
alcuni di essi risultano vuoti. Così mi domandavo: esistono dei
meccanismi di parallelizzazione o bufferizzazione per cui se io faccio
la 'mv' troppo presto, in realtà sto spostando il file prima che
questo venga effettivamente scritto?

Qualcuno sa darmi qualche altra spiegazione al fenomeno?


Non ho mai imparato il Perl perché non mi piace, quindi non conosco le eventuali idiosincrasie del suo I/O; ma posso immaginare che sia necessario fare l'equivalente di fsync() prima di close(), se vuoi essere sicuro che tutti i buffer siano stati svuotati.

La mia immaginazione è corroborata dal fatto che
 apropos fsync
restituisca anche un risultato relativo a Perl:
 aio_fsync (3)        - asynchronous file synchronization
 File::Sync (3pm)     - Perl access to fsync() and sync() function calls
fsync (2) - synchronize a file's in-core state with storage device

...e che "man File::Sync" parli proprio di buffer da svuotare prima di chiamare fsync().

Mi domando, peraltro, perché mai usare system("mv ...") quando Perl avrà sicuramente una funzione rename(). Vedi il mio messaggio di poco fa per una disquisizione più dettagliata sul rename in Linux/Unix.

--
Ciao, Flavio
--
Per iscriversi  (o disiscriversi), basta spedire un  messaggio con OGGETTO
"subscribe" (o "unsubscribe") a mailto:linuxtrent-request@xxxxxxxxxxxxx


Other related posts: