Portál AbcLinuxu, 30. července 2025 02:27


Dotaz: Udržování určité velikosti složky

22.3.2017 22:44 matata | skóre: 13
Udržování určité velikosti složky
Přečteno: 532×
Odpovědět | Admin
Ahoj, lze udržovat soubory ve složce o určité max. velikosti?

Jde mi o to, že bych nechtěl aby složka XY měla více jak např. 100 Gb. Jednou za čas bych pustil script, který by zjistil velikost souborů ve složce a vy případě, že by soubory byly větší než 100 Gb začal by postupně odmazávat nejstarší soubory, až by velikost byla opět jen max. 100 Gb.

Díky moc.
Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

23.3.2017 00:07 OldFrog {Ondra Nemecek} | skóre: 36 | blog: Žabákův notes | Praha
Rozbalit Rozbalit vše Re: Udržování určité velikosti složky
Odpovědět | | Sbalit | Link | Blokovat | Admin
No šlo by to napsat v bashi, ale ten algoritmus pro hledání adeptů na smazání může mít různé varianty podle reálné potřeby. Takže by to mohlo i existovat něco hotového.
-- OldFrog
Jendа avatar 23.3.2017 03:19 Jendа | skóre: 78 | blog: Jenda | JO70FB
Rozbalit Rozbalit vše Re: Udržování určité velikosti složky
Odpovědět | | Sbalit | Link | Blokovat | Admin
Tak například tohle maže podle abecedy (tj. v případě souborů pojmenovaných timestampem od nejstaršího) pokud máš zaplněno přes 90 % disku:
cd /root/capture
for f in `ls *.cfile | sort`; do
  rm "$f"
  perc=`df -H / | grep linuxroot | tr -s " " | cut -d " " -f 5 | tr -d "%"`
  if [ "$perc" -le 90 ]; then
    break
  fi
done
23.3.2017 11:22 lertimir | skóre: 64 | blog: Par_slov
Rozbalit Rozbalit vše Re: Udržování určité velikosti složky
Tak pokud bych se pokusil skrip modifikovat mohlo by fungovat. (ale nepotřebuji jej a tak jsem netestoval)
for f in `ls -rt *`; do
# výpis adresare v reverzním času

  perc=`du -s | cut -f 1`
  # perc je velikost adresáře
  if [ "$perc" -le 100000000 ]; then
  # je-li mensi nez 100G tak skoncit cyklus 
    break
  fi
  rm "$f"
  # smazu nestarsi a pokracuji v cyklu
done
23.3.2017 19:33 Peter Golis | skóre: 65 | blog: Bežné záležitosti | Bratislava
Rozbalit Rozbalit vše Re: Udržování určité velikosti složky
Tá hviezdička vyzerá zaujímavo.
24.3.2017 09:36 lertimir | skóre: 64 | blog: Par_slov
Rozbalit Rozbalit vše Re: Udržování určité velikosti složky
No zapomněl jsem ji smáznout při úpravě skriptu.
24.3.2017 10:56 deVon
Rozbalit Rozbalit vše Re: Udržování určité velikosti složky
perc je velikost adresáře
Ach jo...
24.3.2017 11:50 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: Udržování určité velikosti složky

Spíš bych doporučil

  ls -1rt | while read f; do
    ...
  done

nebo

  while read f; do
  done < <(ls -1rt)

aby se to nerozsypalo při mezeře ve jméno soubotu (která je bohužel celkem běžná), ale až při newline (což naštěstí až tak běžné není).

A taky bych asi nepouštěl du na celý adresář v každé iteraci, ale odečítal velikosti (podle du) mazaných souborů. Pokud tam jsou hardlinky, tak to sice nevyjde správně, ale to by se dalo ošetřit tak, že vnořím dva cykly do sebe, ve vnějším budu kontrolovat celý adresář a ve vnitřním jen počítat velikosti mazaných souborů.

28.3.2017 17:02 RM
Rozbalit Rozbalit vše Re: Udržování určité velikosti složky
Stále stejná chyba, kterou dělají ti, co používají shell jako běžný programovací jazyk, a ne jako macro jazyk (macro procesor). Ohledně mezer by stačilo nastavit IFS, ale jako větší problém vidím to, že pokud nechají expandovat seznam o tisíci položkách v argumentu příkazu for, tak bude mít shell co dělat. Přitom by stačilo použít unixovou rouru, jak jest uvedeno.

Sčítat velikosti je asi rozumné. Pak by možná nebylo špatné použít find:
find . -type f -a -size +1000 -a -size -1100 -printf '%T@ %s %p\n' | sort -n -k2 -r | awk -v maxsize=8887776 '{size+=$2}; size > maxsize{print $3}'
S tím je možné nastavit i další užitečné věci, jako třeba mazání jen souborů určité velikosti, nebo jen do určité hloubky, prostě vše co find nabízí. -- Další rouru a xargs rm nebo while už si každý doplní sám; uvedený příkaz jen generuje list. Já bych to nejspíš udělal ještě tak, aby to zanechalo třeba prázdný soubor s příponou del, pokud bych to mazal někomu jinému.

Josef Kufner avatar 28.3.2017 20:14 Josef Kufner | skóre: 70
Rozbalit Rozbalit vše Re: Udržování určité velikosti složky
Zkus si to svoje na něčem s mezerou v názvu.
Hello world ! Segmentation fault (core dumped)
28.3.2017 20:38 RM
Rozbalit Rozbalit vše Re: Udržování určité velikosti složky
Stačí jen poladit ten awk: {$1="";$2="";print $0}.
Josef Kufner avatar 28.3.2017 20:40 Josef Kufner | skóre: 70
Rozbalit Rozbalit vše Re: Udržování určité velikosti složky
A když bude v názvu "\n"?
Hello world ! Segmentation fault (core dumped)
28.3.2017 20:52 RM
Rozbalit Rozbalit vše Re: Udržování určité velikosti složky
Pokud bude awk a sort podporovat \0 pak stačí změnit ten delimiter u find, ale mne to nějak sort nebral a nechce se mi hledat příčina. Teoreticky by to jít s GNU sort a awk mělo, po nastavení příslušných separátorů, tj. sort -t a awk RS. Pak to ale znamená použít za rourou xargs -0, protože shell (while) jak známo \0 nepodporuje.
28.3.2017 20:49 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: Udržování určité velikosti složky
pokud nechají expandovat seznam o tisíci položkách v argumentu příkazu for, tak bude mít shell co dělat

Pokud se nebavíme o nějakém extrémně slabém stroji, tak s tisícem položek bash rozhodně problém mít nebude. Pro jistotu jsem zkusil porovnat rychlost

  for f in *; do echo "$f"; done >/dev/null
  ls | while read f; do echo "$f"; done >/dev/null
v adresáři s 10000 soubory (kvůli potlačení nesouvisejících vlivů na tmpfs). U prvního příkazu vycházelo průměrně 59 ms, u druhého 119 ms. I pro 100000 souborů vycházejí obě čísla přibližně desetkrát vyšší, takže poměr je pořád stejný.
28.3.2017 23:00 RM
Rozbalit Rozbalit vše Re: Udržování určité velikosti složky
Máte pravdu, ještě jsem to zkoušel a mezi for a while skutečně není rozdíl, pokud se použije pro vytvoření seznamu souborů stejný příkaz. (Nevím už jak jsem k tomu kdysi dospěl.) Většinou používám v takových případech napojení na xargs nebo awk, to je rychlejší a nechá se použít \0. Hodilo by se vědět jak s tím shell ve skutečnosti pracuje, jestli využívá rouru nebo si data nejprve uloží do paměti. -- Zatím to tedy vypadá, že for to sosá rovnou přes fifo pokud má v argumentu program volaný jako samostatný proces nebo spuštěný další subshell (v případě samotného globbingu si to zpracuje interně). -- Třeba někdo vysvětlí. Já ten shell zas tak moc nemusim a pro tohle bych možná raději volil Perl, pokud by to mělo být složitější.
Josef Kufner avatar 28.3.2017 20:17 Josef Kufner | skóre: 70
Rozbalit Rozbalit vše Re: Udržování určité velikosti složky
Toto vlákno je krásnou ukázkou toho, proč není dobrý nápad programovat v Bashi.
Hello world ! Segmentation fault (core dumped)
Josef Kufner avatar 28.3.2017 20:39 Josef Kufner | skóre: 70
Rozbalit Rozbalit vše Re: Udržování určité velikosti složky
Odpovědět | | Sbalit | Link | Blokovat | Admin
Příloha:
Tady máš implementaci v PHP. Nebude to mít problém s jakýmkoliv názvem souboru (narozdíl od těch skriptů výše) a je docela snadné tam přidat komplikovanější podmínky.

V současné podobě to ukáže seznam souborů od nejnovějšího po nejstarší a ukáže čáru, od které to má vše smazat. Samotné mazání je zakomentované. Předpokládám jen soubory, na rekurzivní mazání adresářů i na zjišťování velikosti bude potřeba použít chytřejší funkce.
Hello world ! Segmentation fault (core dumped)
29.3.2017 00:14 RM
Rozbalit Rozbalit vše Re: Udržování určité velikosti složky
Odpovědět | | Sbalit | Link | Blokovat | Admin
Doladil jsem to. Nyní může být v názvu i \n. Místo echo za system() stačí použít rm a mělo by to mazat (nezkoušel jsem). V Awk se nechá programovat podobně jako v C, takže se nechá vymyslet jakákoliv složitější podmínka.
find . -type f -a -size +100M  -printf '%T@ %s %p\0' | sort -z -r -n -k1 | awk -v RS="\0" -v maxsize=1300000000 '{size+=$2}; size > maxsize{$1="";$2="";system("echo \047"$0"\047")}'
One-liner tedy začne odstranňovat (nyní jen vytiskne) soubory z aktuálního adresáře při zaplnění adresáře soubory o velikosti nad 1.3G. Odstraňovat se budou jen soubory > 100M. \047 jsou apostrofy, které mají chránit argument před expanzí shellu (snad to funguje).
29.3.2017 00:54 RM
Rozbalit Rozbalit vše Re: Udržování určité velikosti složky
ještě prosím před system() vložit ;sub(/ */,""); pro odmazání mezer na začátku, které tam z nějakého důvodu zůstanou po $1="" a $2="".

Příkaz system() spouští vždy shell, takže pokud je /bin/sh nastaveno na bash, může to být docela pomalé. Pak by bylo přecejen vhodné použít rouru a xargs -0 nebo xargs -0 -l1
...;$2="";sub(/* /,""); printf "%s\0", $0}' | xargs -0 echo
takto se spustí echo (tedy rm) jen jednou a bez shellu a všechny znaky jsou brány jako obyčejné (už žádné metaznaky není třeba ošetřovat).
29.3.2017 00:59 RM
Rozbalit Rozbalit vše Re: Udržování určité velikosti složky
oprav: sub(/^ */,"")

Už je pozdě ;).

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.