xargs
を使用する多くの単純なコマンドは、サブシェルを使用するコマンドとして書き直すことができます。たとえば、サブシェルとxargsを使用して記述された、/usr/bin
の最大の10個のバイナリを連結するために今日使用していたものを次に示します。
サブシェル:
$ cat $(du -sh /usr/bin/* | sort -h | tail | cut -d " " -f 2 | tr "\n" " ")
xargs
:
$ du -sh /usr/bin/* | sort -h | tail | cut -d " " -f 2 | tr "\n" " " | xargs cat
では、いつサブシェルを使用する必要があり、いつxargs
を使用する必要がありますか?
カットの区切り文字はハードタブであり、SEでは正しく表示されないようです。
これは少し意見の分かれる質問ですが、私はこれを言います、それは2つのことに大きく依存しています:
同じプロセスを数十から数百実行する可能性が高い場合は、xargs
が最も理にかなっています。また、プロセスの起動に費用がかかる場合は、xargs
が最適なルートである可能性があります。
ただし、コマンドのインスタンスがほんの一握りしかない場合は、サブシェルで実行しても問題ありません。
サブシェルによって生成される引数の長さが非常に長くなる場合は、xargs
を使用することをお勧めします。ただし、この制限はかなり極端で、通常は2MB〜4MBの文字であるため、これを超えることはほとんどありません。次のように確認できます。
$ xargs --show-limits < /dev/null
Your environment variables take up 4805 bytes
POSIX upper limit on argument length (this system): 2090299
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 2085494
Size of command buffer we are actually using: 131072
ちなみに、これらのコマンドはどちらも機能していないようです。 cut -d " " -f2
は無効です。cut
は区切り文字として1文字しか使用できません。代わりにこれを試してください:
$ du -sh /usr/bin/* | sort -h | awk 'NR<=10 {print $2}' | tr "\n" " "
-or-
$ du -sh /usr/bin/* | sort -h | tail | cut -f2- | tr "\n" " "
ここでawk
を使用すると、スペースを含むファイル名またはディレクトリがある場合に問題が発生する可能性があるため、注意して使用してください。
$ ll
total 0
-rw-rw-r--. 1 saml saml 0 Feb 22 19:47 file 1
-rw-rw-r--. 1 saml saml 0 Feb 22 19:47 file 2
$ du -sh * | sort -h | awk 'NR<=10 {print $2}' | tr "\n" " "
file file $
私はcut -f2-
メソッドを使用しますが、それは私だけです。他の人は、より洗練されたawk
ソリューションを提供するかもしれませんが、最も意味のあるものを使用してください。
注:出力をxargs
にパイプする場合、cat
を呼び出す必要はありません。デフォルトでは、xargs
は渡された出力を自動的にエコーします。
$ du -sh * | sort -h | tail | cut -f2- | tr "\n" " " | xargs
file 1 file 10 file 2 file 3 file 4 file 5 file 6 file 7 file 8 file 9
タブを使用してカットで区切る場合、明示的に行う必要はありません。デフォルトではそのようになっています。
-d, --delimiter=DELIM
use DELIM instead of TAB for field delimiter