Esiste un modo più rapido per verificare se un file è in uso?


8

Sto cercando una funzione da riga di comando o una funzione c che mi farà sapere se un file è aperto / in uso da qualcosa.

lsofe fuserlo dico, ma forniscono molte altre informazioni che si traducono in circa 300 ms in alcune situazioni (come quando uso questo codice su MAC OS X, sto deviando per Linux e OS X) (ho un Windows soluzione che richiede 5ms, quindi sto cercando di trovare qualcosa in Unix che sia anche molto veloce e restituisca vero o falso se il file è in uso)


Risposte:


9

Se si utilizza questo come un blocco, non funzionerà in quanto né lsofo fuserprevenire condizioni di gara.

Il processo di base che lsoffa è scorrere tutti i processi alla /proc/*/fsricerca di descrittori di file aperti. Ci vorrà del tempo, qualunque cosa tu faccia.

Puoi farlo da solo, ma non è probabile che sia più veloce in quanto devi controllare ogni processo aperto sul sistema.

Se quello che stai facendo è fondamentale per il tempo, cerca un altro modo per farlo.

  • Se controlli il file tramite un programma che hai scritto; usa un file di blocco.
  • Se si esegue un comando che opera sul file, cercare e vedere quale documentazione offre quel comando / programma e vedere se non è possibile creare un file di blocco. In caso contrario, vedere se non è possibile creare un file con il suo PID al suo interno. Quindi puoi /proc/<PID>/fsvedere se il tuo file è attualmente aperto o meno. Osservando solo un processo, i descrittori di file aperti saranno molto più veloci della mappatura di tutti.
  • Altrimenti, per aiutarti, avrò bisogno di maggiori informazioni su ciò che stai facendo.

In un commento hai fornito ulteriori informazioni per stabilire se Firefox è in esecuzione su un determinato sistema. Il modo migliore per farlo è cercare i file di blocco di Firefox. Questi sono memorizzati nelle posizioni predefinite specificate nel wiki di Mozilla.

Ad esempio, su Linux, chiedi al tuo programma di eseguire le seguenti operazioni:

  • aprire la ~/.mozilla/firefox/directory.
  • Elenca tutte le directory, filtrando le directory che terminano con .default. (Penso che tutti i profili finiscano con .default, se non semplicemente strisciano in ogni directory.)
  • In ogni directory sopra, cerca l'esistenza di un file chiamato locko .parentlock. Se vedi uno o entrambi i file, Firefox è aperto.

Questo algoritmo dovrebbe essere eseguito più velocemente di quello che fai attualmente su Windows.


Ottima risposta grazie. Esiste un modo per dire a lsof e fuser di controllare la cartella pid solo se è Firefox? Ciò farebbe saltare tutto il contenuto delle cartelle tranne le cartelle di Firefox (ho 3 istanze
separate,

Il file è bloccato, ma non riesco a capire come testare se è bloccato. Si sta aprendo con successo per lettura / scrittura. È così strano. Ho provato fcntl da c ma è sempre tornato -1 :(
Noitidart

3
@Noitidart Qual è il tuo vero problema che stai cercando di risolvere? Per cercare i descrittori di file aperti di qualsiasi processo devi conoscere il suo PID. Questo cambia per ogni istanza del programma. Un modo semplice per farlo "manualmente" è con ps aux firefox. Prendi quei PID e cercali nel /proc/filesystem.
nixeagle,

ah grazie è una buona idea ps aux firefox. Bene, la mia situazione esatta è: ho il percorso di un file. È bloccato se Firefox è in esecuzione. Voglio vedere se è bloccato o non dire se Firefox è in esecuzione.
Noitidart,

1
@Noitidart Ho modificato il mio commento per includere come rilevare firefox guardando i file di blocco. Puoi ripetere questo processo su tutti i sistemi.
nixeagle,

1

TL; DR

In uno dei tuoi commenti , dichiari:

Bene, la mia situazione esatta è: ho il percorso di un file. È bloccato se Firefox è in esecuzione. Voglio vedere se è bloccato o non dire se Firefox è in esecuzione.

La tua domanda originale sui lockfile sembra essere molto lunga quando ci sono modi più semplici per scoprire se Firefox è in esecuzione per un determinato utente e per controllarne lo stato del processo.

Stato del processo d'esame

Un modo più ragionevole per trovare il PID di un dato processo è usare pgrep dal pacchetto procps . Per esempio:

$ pgrep -u $LOGNAME firefox
5671

È quindi possibile ispezionare lo stato del PID con ps :

$ ps 5671
  PID TTY      STAT   TIME COMMAND
 5671 ?        Sl   105:47 /usr/lib/firefox/firefox

o semplicemente ottenere le bandiere di stato senza nessun'altra cruft:

$ ps -ho stat $(pgrep -u $LOGNAME firefox)
Sl

Un mio sistema, il one-liner sopra richiede costantemente solo 1,4 millisecondi per essere completato. Il tuo chilometraggio può variare.

Codici di stato del processo

La sezione CODICI DI STATO DI PROCESSO di ps (1) indica in dettaglio il significato dei vari flag di stato. Su Ubuntu 14.04 la pagina man dice:

PROCESS STATE CODES
       Here are the different values that the s, stat and state output
       specifiers (header "STAT" or "S") will display to describe the state of
       a process:

               D    uninterruptible sleep (usually IO)
               R    running or runnable (on run queue)
               S    interruptible sleep (waiting for an event to complete)
               T    stopped, either by a job control signal or because it is
                    being traced
               W    paging (not valid since the 2.6.xx kernel)
               X    dead (should never be seen)
               Z    defunct ("zombie") process, terminated but not reaped by
                    its parent

       For BSD formats and when the stat keyword is used, additional
       characters may be displayed:

               <    high-priority (not nice to other users)
               N    low-priority (nice to other users)
               L    has pages locked into memory (for real-time and custom IO)
               s    is a session leader
               l    is multi-threaded (using CLONE_THREAD, like NPTL pthreads
                    do)
               +    is in the foreground process group

1
il problema è che ha bisogno di sapere in quale sessione è attualmente Firefox. Su Linux, cerchi semplicemente ~/.mozilla/firefox/*/lock. È quindi possibile identificare la sessione guardando il nome della directory principale di ciascun file di blocco. Su altre piattaforme questo non funziona. La nostra chat spiega di più su come farlo funzionare su Mac (che è un po 'irrilevante per Ubuntu, ma il gioco è fatto). Per essere onesti, dovrebbe davvero aggiornare la domanda per essere più specifici. : P
nixeagle,
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.