Pro rozšíření odpovědi @Alex Gitelman:ano, je rozdíl mezi "standardním vstupem" a příkazovým řádkem.
Když napíšete rm a.txt b.txt c.txt
, soubory, které uvádíte po rm
jsou známé jako argumenty a jsou zpřístupněny rm prostřednictvím speciální proměnné (nazvané argv
vnitřně). Na druhou stranu standardní vstup vypadá na unixový program jako soubor s názvem stdin
. Program může číst data z tohoto "souboru" stejně, jako kdyby otevřel běžný soubor na disku a četl z něj.
rm
, stejně jako mnoho jiných programů, přebírá své argumenty z příkazového řádku, ale ignoruje standardní vstup. Můžete do ní zapít cokoli chcete; ta data prostě zahodí. To je místo xargs
přijde vhod. Čte řádky na standardním vstupu a převádí je na argumenty příkazového řádku, takže můžete efektivně přenášet data do příkazového řádku jiného programu. Je to skvělý trik.
Například:
find . -name ".txt" | xargs rm
find . -name ".txt" | grep "foo" | xargs rm
Pamatujte, že toto nebude fungovat správně, pokud budou nějaké názvy souborů obsahující nové řádky nebo mezery. Chcete-li se vypořádat s názvy souborů obsahujícími nové řádky nebo mezery, měli byste místo toho použít:
find . -name ".txt" -print0 | xargs -0 rm
To řekne find
k ukončení výsledků znakem null namísto nového řádku.Nicméně grep
nebude fungovat jako předtím. Místo toho použijte toto:
find . -name ".txt" | grep "foo" | tr "\n" "\0" | xargs -0 rm
Tentokrát tr
se používá k převodu všech nových řádků na prázdné znaky.
"proč nemohu pomocí kanálu najít výsledek do rm?"
Když něco přenesete do programu, roura nahradí vstup z klávesnice. Mějte to na paměti a položte si následující otázku:Co by rm
dělat s klávesnicí? Smazat stisknuté klávesy? (opravdu trochu hloupé) Přijímáte interaktivní ovládání? (rm
není interaktivní, kromě případů, kdy potřebuje potvrzení, které může být skutečně poskytnuto rourou.)
Ve skutečnosti, když rm
již běží, nemůžete zadávat příkazy, které mu umožní smazat soubory....takže to nemůžete udělat ani s roura.
Pokud budete mít na paměti, že kombinaci klávesnice/obrazovky nahrazuje dýmka, věci se okamžitě zdají logičtější.
Nyní naopak. Datový tok můžete kanálem grep
.Znamená to, že můžete místo toho nechat grep číst úhozy z vaší klávesnice jako vstupní data?
ANO! To je vlastně to, co nativně (bez potrubí) dělá.
(mimo jiné si uvědomte, že argument hledání nemůžete pomocí kanálu ani zadat do grep
)
Nyní tedy víte, proč nemůžete potrubí do rm a očekávat, že bude fungovat jako argument příkazového řádku.
tl;dr :
Anatomie programu podle filozofie UNIX:
zařadit, zařadit, zapnout klávesnici, vypnout obrazovku. -> Pipe pouze nahrazuje klávesnici a obrazovku.
Pipe posílá výstup prvního příkazu na standardní vstup druhého. rm
nepřijímá standardní vstup, takže se k němu nemůžete připojit. Můžete použít xargs
k dosažení stejného efektu. Můžete najít příklad pro xargs
speciálně pro váš případ v manuálové stránce pro xargs.