Řekněme, že mám jednoduchý hloupý skript, který odstraňuje soubory ukončením, vypadá takto:
rm *.uvw *.xyz
Skript neboli rm
, abych byl přesný, zapisuje zprávy na stderr, pokud nemůže najít alespoň jeden soubor se zadanou koncovkou.
Nyní řekněme, že skript je o něco větší a dělá o něco více s o něco více typy souborů a nezajímá mě, které typy souborů existují a které ne, ale stížnosti na neexistující typy souborů brání zbytku výstup a chybové zprávy mě zajímají více, takže chci výstup filtrovat:
rm *.uvw *.xyz 2>&1 | grep -v "No such file or directory"
Z velké části to funguje dobře, ale odstraní se tím část se zprávou z interaktivních dialogů, která se například ptají, zda má být smazán soubor chráněný proti zápisu, takže jsem vyzván bez příslušné zprávy.
Nerozumím tomuto chování a nemohl jsem najít žádné související informace. Může to někdo vysvětlit?
Přijatá odpověď:
Problém
Když rm vyzve k použití pro vstup, nevloží nový řádek na konec výzvy:
$ rm *.uvw *.xyz
rm: remove write-protected regular empty file 'a.xyz'?
grep
je linkový. Dokáže zpracovat pouze celé řádky. Nemůže zjistit, zda má být řádek vytištěn, dokud není řádek kompletní. Tedy standardní nástroje pro práci s ukládáním do vyrovnávací paměti, jako je stdbuf
, nemůže pomoci.
Řešení
Použijte nullglob a odstraňte zprávy o chybějících souborech.
Bez nullglob se zobrazí zprávy, které nechcete:
$ rm *.uvw *.xyz
rm: cannot remove '*.uvw': No such file or directory
rm: remove write-protected regular empty file 'a.xyz'? n
S tím je potlačena zpráva „Žádný takový soubor nebo adresář“:
$ shopt -s nullglob
$ rm *.uvw *.xyz
rm: remove write-protected regular empty file 'a.xyz'? n
Upřesnění
Pokud neexistuje žádný soubor, který by odpovídal některému globu, objeví se jiná chybová zpráva:
$ shopt -s nullglob
$ rm *.uvw *.xyz
rm: missing operand
Try 'rm --help' for more information.
Jednoduchým způsobem, jak se tomu vyhnout, je ujistit se, že alespoň jeden takový soubor existuje:
shopt -s nullglob
[ -e "deleteme.xyz" ] ||touch deleteme.xyz
rm *.uvw *.xyz
Od deleteme.xyz
bude stejně vymazán, není na škodu se ho dotknout, než spustíme rm
.