GNU/Linux >> Znalost Linux >  >> Linux

Zjistit, zda je soubor v procesu zápisu?

Řešení 1:

Nejlepším řešením je použít lsof zjistit, zda byl soubor otevřen nějakým procesem:

#  lsof -f -- /var/log/syslog
COMMAND   PID   USER   FD   TYPE DEVICE SIZE/OFF  NODE NAME
rsyslogd 1520 syslog    1w   REG  252,2    72692 16719 /var/log/syslog

Nemůžete snadno zjistit, zda se do něj zapisuje, ale pokud se do něj zapisuje, MUSÍ být otevřené.

Edit:pojďme raději řešit skutečný problém zde, než se snažit implementovat navrhované řešení!

K přenosu souboru použijte rsync:

○ → rsync -e ssh remote:big.tar.gz .

Tímto způsobem nebude soubor zkopírován přes existující soubor, ale zkopírován do dočasného souboru (.big.tar.gz.XXXXXX ), dokud se přenos nedokončí, poté jej přesunete na místo.

Řešení 2:

Jste na správné cestě, přejmenování souboru je atomická operace, takže provedení přejmenování po nahrání je jednoduché, elegantní a není náchylné k chybám. Další přístup, který mě napadá, je použití lsof | grep filename.tar.gz zkontrolovat, zda k souboru přistupuje jiný proces.

Řešení 3:

Trochu staré, ale většina odpovědí zcela postrádá smysl otázky:

Ale napadlo mě, že se pokusím zjistit, jestli existuje způsob, jak zjistit, zda je soubor celý nejprve na příkazovém řádku...

Obecně není. Jednoduše nemáte dostatek informací, abyste to mohli určit.

Protože určení, že soubor je zavřený není totéž jako určení, zda je soubor celý . Soubor se například „uzavře“, pokud se spojení v průběhu přenosu ztratí.

Pouze odpověď @Alex má pravdu. A dokonce i on propadl používání lsof poněkud.

Chcete-li zjistit, zda byl soubor zcela dokončen, vyžaduje úspěšný přenos více dat. Například:

Jedna alternativa, o které jsem přemýšlel, bylo nechat soubor zkopírovat jako jinou příponu souboru (například .tar.gz.part ) a poté přejmenován na .tar.gz po dokončení přenosu.

To je naprosto skvělý způsob, jak sdělit, že soubor byl plně a úspěšně přenesen. Můžete také přesouvat soubory z jednoho adresáře do druhého, pokud zůstanete ve stejném souborovém systému. Nebo požádejte odesílatele, aby poslal prázdný filename.done soubor signalizovat dokončení.

Všechny metody se ale musí spoléhat na to, že odesílatel nějakým způsobem signalizuje, že přenos byl úspěšně dokončen. Protože tyto informace má pouze odesílatel.

Některé formáty souborů (například PDF) obsahují data, která umožňují určit, zda je soubor úplný. Ale musíte otevřít a přečíst téměř celý soubor, abyste to zjistili.

lsof pouze vám řekne, že soubor již není otevřený – neřekne vám proč už to není otevřené. Ani vám neřekne, jak velký soubor má být.

Řešení 4:

Nejlepší způsob, jak toho dosáhnout, je použít incron ("inotify cron systém"). Umožňuje vám nastavit inotify watch na adresář, který vás pak bude upozorňovat na operace se soubory. V tomto případě byste měli sledovat adresář close_write. To vám umožní spustit příkaz, jakmile byl soubor po zápisu uzavřen.

Řešení 5:

Zdá se, že lsof dokáže zjistit, v jakém režimu je soubor otevřen:

lsof -f -- a_file
COMMAND   PID  USER   FD   TYPE DEVICE SIZE/OFF     NODE NAME
cat     52391 bob    1w   REG    1,2       15 19545007 a_file

Vidíš, kde je napsáno 1w? To znamená, že číslo deskriptoru souboru je 1 a režim je w, neboli zápis.


Linux
  1. Jak zjistit, který proces vytváří soubor?

  2. The Bash ‘?

  3. Je MV Atomic na Fs?

  1. Tail -f, určit, zda se do souboru již nezapisuje?

  2. Jak zjistím, zda souborový systém v .net rozlišuje malá a velká písmena?

  3. Proč rozvětvení mého procesu způsobuje nekonečné čtení souboru

  1. Jak mohu zjistit, který proces má soubor otevřený v Linuxu?

  2. Chování rsync se souborem, který se stále zapisuje?

  3. Který soubor v /proc čte jádro během procesu spouštění?