「xargs ls」を並列に実行すると誤った出力

「xargs ls」を並列に実行すると誤った出力

/usr/使用しているすべてのファイルを一覧表示したいですlsls直接電話する代わりにxargs。また、xargsパラメータを使用し-L-Pすべてのコアを活用しています。

find /usr/ -type f  -print0 | xargs -0 -L16 -P4 ls -lAd  | sort -k9 > /tmp/aaa

上記のコマンドは期待どおりに機能します。良い出力を作り出します。ただし、行パラメータの数を-L16から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

ここで何が起こっているのかを説明できる人はいますか?

答え1

これはパイプへの書き込みに関連しています。 16個のファイルごとに1つのプロセスを実行するため、-L16ファイル名の長さに応じて約1000文字になります。あなたと一緒にいる人は約4000人です-L64。このlsプログラムはほぼ確実にstdioライブラリを使用し、書き込み呼び出しの数を減らすために出力に4kBのバッファを使用することはほぼ確実です。

したがって、findは多数のファイル名を生成し、(-L64の場合)xargsを64個のファイル名に分割し、lsそれを処理するために4つのプロセスを開始します。それぞれはls最初の4k出力を生成し、ソートのためにパイプラインに書き込みます。この4kは通常いいえ改行文字で終わります。だから、3番目が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情報を再検索するために追加のプログラムを実行するのではなく、すでに持っている情報を出力するだけです。

答え2

GNU Parallelは、混合問題を正確に解決するために作成されました(実行時間40秒):

find /usr/ -type f  -print0 | parallel -0 -L64 -P4 ls -lAd  | sort -k9 > /tmp/bbb

コア数(実行時間40秒)も検出します。

find /usr/ -type f -print0 | parallel -0 -L64 ls -lAd  | sort -k9 > /tmp/bbb

入力を均等に分割します(実行時間24秒)。

find /usr/ -type f -print0 | parallel -0 -X ls -lAd  | sort -k9 > /tmp/bbb

関連情報