私はこれについてかなり混乱しています。いくつかの説明が必要です。
例1:
pgrep string | xargs ps
例2:
find . | xargs grep whatever
例1から、次のように収集します。
実行中のプロセスの名前の一部である「文字列」を検索し、すべての一致のプロセスIDを「xargsps」に返します->一致にpsを追加するだけです(プロセスID自体です)。として出力:
ps <processid>
この場合、誰かがxargsが実際に何をするのか説明できますか?
例2から、次のように収集します。
現在の作業ディレクトリから再帰的に「文字列」を検索することです。ここで、「xargs」はどのように正確に機能しますか?
私は、「xargs」が標準入力からxargsに与えられた「引数」(通常はそれ自体がUNIXコマンド)にデータを繰り返し追加するという意見でした。
Xargs()のマニュアルページから:
xargsは、空白(二重引用符または一重引用符または円記号で保護できます)または改行で区切られた標準入力から項目を読み取り、コマンド(デフォルトは/ bin/echo)を1回以上実行し、その後に初期引数を付けます。標準入力から読み取られた項目による。標準入力の空白行は無視されます。
一般的にxargsはこのように使用されます
prog | xargs utility
ここで、prog
は、1つ以上の改行/スペースで区切られた結果を出力することが期待されています。秘訣は、xargs
が必ずしも結果ごとに1回utility
を呼び出すとは限らず、代わりに結果をサブリストに分割し、すべてのサブリストに対してutility
を呼び出すことです。 xargsがすべての結果に対してutility
を呼び出すように強制する場合は、xargs -L1
を使用して呼び出す必要があります。
xargs
は、utility
に送信されるサブリストがARG_MAX
よりも短いことを約束していることに注意してください(興味がある場合は、ARG_MAX
を使用してgetconf ARG_MAX
の現在の値を取得できます)。これにより、これらを回避できます。恐ろしい "引数リストを長くする"エラー。
Xargsが行うことの良い例は、findを使用してディレクトリ内のすべてのファイルのソートされたチェックサムを取得しようとすることです。
find . | cksum | sort
チェックサムを1つだけ返しますが、それが何のチェックサムであるかは明確ではありません。私たちが望むものではありません。パイプは、stdoutをfindからcksumのstdinに送信します。 cksumが本当に必要としているのは、コマンドライン引数のリストです。
cksum file001.blah file002.blah file003.blah
必要なチェックサムを含む3行をファイルごとに1つずつ報告します。 Xargsは、前のプログラムのstdoutを一時的な非表示のコマンドラインに変換して次のプログラムにフィードするという手品を実行します。動作するコマンドラインは次のとおりです。
find . | xargs cksum | sort
Xargsとcksumの間にパイプがないことに注意してください。
$ echo 'line1
> line2
> line3
> ...
> lineN ' | xargs cmd1 -a -b
結果は次のようになります。
$ cmd1 -a -b line1 line2 line3 ... lineN
xargs
は、行数が大きくなりすぎると、cmd1 ...
をcmd1
の複数の実行に分割します。
xargs
は、位置引数としてstdin
行を渡すことに関連する他の多くのタスクに使用できます。コマンドの複数のインスタンスを並行して実行するための xargs(1) の大文字の-P
オプションを見てください。
xargsは通常、引数をグループ化するために使用されるため、コマンドに多数の引数を渡したときに発生する「引数が多すぎます」というエラーは発生しません。
#!/bin/sh
#script to echo out the arguments 1 at a time!
for a in $*
do
echo $a
done
コマンド
$sh myscript 1 2 3 4 5
降伏します
1
2
3
4
5
だが
$sh myscript 1 2 3 4 5 6 7 8 9 10 11
パラメータの最大数を超えているため、機能しません(実際には最大数がわからないが、この例では10としましょう!)
これを回避するには、
#!/bin/sh
#script to echo out the arguments 1 at a time!
for a in $*
do
echo $a | xargs echo
done
その後、このように実行できます
$sh myscript "1 2 3 4 5" "6 7 8 9 10 11"
パラメータが2つしかないため、正しい結果が得られます