Ř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.