Find
並行執行“xargs ls”時輸出亂碼
我想列出
/usr/
using中的所有文件ls
。我不是ls
直接打電話,而是通過xargs
. 此外,我正在使用xargs
參數-L
並-P
利用我所有的核心。find /usr/ -type f -print0 | xargs -0 -L16 -P4 ls -lAd | sort -k9 > /tmp/aaa
上面的命令按預期工作。它產生了很好的輸出。但是,當我將行
-L
數參數從 16 增加到 64 時:find /usr/ -type f -print0 | xargs -0 -L64 -P4 ls -lAd | sort -k9 > /tmp/bbb
結果輸出都是亂碼。我的意思是,輸出不再從新行開始,新行從“上一個”行的中間開始並且都混在一起:
-rw-r--r-- 1 root root 5455 Nov 16 2010 /usr/shareonts/X11/encodings/armscii-8.enc.gz -rw-r--r-- 1 root root 1285 May 29 2016-rw-r--r-- 1 root root 6205 May 29 2016 /usr/include/arpa/nameser_compat.h -rw-r--r-- 1 root root 0 Apr 17 20-rw-r--r-- 1 root root 933 Apr 16 2012 /usr/share/icons/nuoveXT2/16x16/actions/address-book-new.png -rw-r--r-- 1 root root 53651 Jun 17 2012-rw-r--r-- 1 root root 7117 May 29 2016 /usr/include/dlfcn.h -rw-r--r-- 1 root root 311 Jun 9 2015-rw-r--r-- 1 root root 1700 Jun 9 2015 /usr/share/cups/templates/de/add-printer.tmpl -rw-r--r-- 1 root root 5157 M1 root root 10620 Jun 14 2012 /usr/lib/perl5/Tk/pTk/tkIntXlibDecls.m -rw-r--r-- 1 root -rwxr-xr-x 1 root root 1829 Jan 22 2013 /usr/lib/emacsen-common/packages/install/dictionaries-common -rw-r--r-- 1 root r-rw-r--r-- 1 root root 1890 Jun 2 2012 /usr/share/perl5/Date/Manip/TZ/afaddi00.pm -rw-r--r-- 1 root root 1104 Jul-rw-r--r-- 1 root root 10268 Jul 27 15:58 /usr/share/perl/5.14.2/B/Debug.pm -rw-r--r-- 1 root root 725 Apr 1-rw-r--r-- 1 root root 883 Apr 1 2012 /usr/share/icons/gnome/16x16/actions/address-book-new.png
有趣的是,它只在使用
-L64
或更大時發生。我沒有看到這個問題-L16
。誰能解釋這裡發生了什麼?
這與寫入管道有關。您為每 16 個文件執行一個程序,
-L16
這會產生大約一千個字元,具體取決於文件名的長度。和-L64
你一起大約有四千人。該ls
程序幾乎可以肯定使用 stdio 庫,並且幾乎可以肯定使用 4kB 緩衝區用於輸出以減少寫入呼叫的次數。因此 find 會產生大量文件名,然後(對於 -L64 情況)xargs 將它們分成 64 個包並啟動 4 個
ls
程序來處理它們。每個都ls
將生成其前 4k 的輸出並將其寫入管道進行排序。請注意,此 4k 通常不會以換行符結尾。所以說第三個ls
首先準備好它的第一個 4kB,然後它就結束了lrwxrwxrwx 1 root root 6 Oct 21 2013 bzegrep -> bzgrep -rwxr-xr-x 1 root root 4877 Oct 21 2013 bzexe lrwxrwxrwx 1 root root 6 Oct 2
然後第一個 ls 輸出一些東西,例如
total 123459
那麼排序的輸入將包括
lrwxrwxrwx 1 root root 6 Oct 2total 123459
在這種
-L16
情況下,這些ls
過程將(通常)一次只輸出一組完整的結果。當然,對於這種情況,您使用 xargs 和 ls 只是在浪費時間和資源,您應該只
find
輸出它已經擁有的資訊,而不是執行額外的程序來再次發現資訊。