Xargs neden gereklidir?


25

Bir dizindeki "notes.txt" adlı bir dosya dışındaki tüm dosyaları kaldırmak istediğimi varsayalım. Bunu boru hattıyla yapardım ls | grep -v "notes.txt" | xargs rm. İkinci borunun çıkışı rm'nin kullanması gereken girişse neden xargs'a ihtiyacım var?

Karşılaştırma amacıyla, boru hattı, echo "#include <knowledge.h>" | cat > foo.cyinelenen metni xargs kullanmadan dosyaya ekler. Bu iki boru hattı arasındaki fark nedir?


3
Çıktıyı ayrıştırmakls | grep -v "notes.txt" | xargs rm dışında notes.txtveya genel olarak hiçbirls şeyi kaldırmak için kullanmamalısınız . Örneğin, tek bir dosyada boşluk varsa komutunuz bozulur. Daha güvenli bir yol olacağını rm !(notes.txt)(ile Bash shopt -s extglobseti) veya rm ^notes.txtZsh içinde (ile EXTENDED_GLOBvs.)
slhck

Boşluklardan kaçınmak için :-) find . -maxdepth 1 -mindepth 1 -print0 | xargs -0yerine yapabilirsinizls | xargs
flob

Yanıtlar:


35

Çok farklı iki girdi türünü karıştırıyorsunuz: STDIN ve argümanlar. Bağımsız değişkenler, genellikle komut adından sonra belirterek (ör. echo these are some argumentsVeya rm file1 file2) , komuta başlarken sağlanan dizelerin listesidir . STDIN, diğer taraftan, komutun başladıktan sonra okuyabileceği (isteğe bağlı olarak) bir bayt akışıdır (bazen metin, bazen değil). İşte bazı örnekler ( catargümanları ya da STDIN alabilen not , ancak onlarla farklı şeyler yapar):

echo file1 file2 | cat    # Prints "file1 file2", since that's the stream of
                          # bytes that echo passed to cat's STDIN
cat file1 file2    # Prints the CONTENTS of file1 and file2
echo file1 file2 | rm    # Prints an error message, since rm expects arguments
                         # and doesn't read from STDIN

xargs STDIN tarzı girdiyi bağımsız değişkenlere dönüştürmek olarak düşünülebilir:

echo file1 file2 | cat    # Prints "file1 file2"
echo file1 file2 | xargs cat    # Prints the CONTENTS of file1 and file2

echo aslında aşağı yukarı tam tersini yapar: argümanlarını STDOUT'a dönüştürür (başka bir komutun STDIN'ine aktarılabilir):

echo file1 file2 | echo    # Prints a blank line, since echo doesn't read from STDIN
echo file1 file2 | xargs echo    # Prints "file1 file2" -- the first echo turns
                                 # them from arguments into STDOUT, xargs turns
                                 # them back into arguments, and the second echo
                                 # turns them back into STDOUT
echo file1 file2 | xargs echo | xargs echo | xargs echo | xargs echo    # Similar,
                                 # except that it converts back and forth between
                                 # args and STDOUT several times before finally
                                 # printing "file1 file2" to STDOUT.

9

catgiriş alır STDINve rmalmaz. Bu tür komutlar xargsiçin STDINsatır satır yineleme yapmanız ve komutları komut satırı parametreleriyle yürütmeniz gerekir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.