Find

並行執行“xargs ls”時輸出亂碼

  • March 4, 2017

我想列出/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輸出它已經擁有的資訊,而不是執行額外的程序來再次發現資訊。

引用自:https://unix.stackexchange.com/questions/332474