web-dev-qa-db-ja.com

UNIXコマンドxargsを理解する

私はこれについてかなり混乱しています。いくつかの説明が必要です。

例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回以上実行し、その後に初期引数を付けます。標準入力から読み取られた項目による。標準入力の空白行は無視されます。

26
halluc1nati0n

一般的にxargsはこのように使用されます

prog | xargs utility

ここで、progは、1つ以上の改行/スペースで区切られた結果を出力することが期待されています。秘訣は、xargsが必ずしも結果ごとに1回utilityを呼び出すとは限らず、代わりに結果をサブリストに分割し、すべてのサブリストに対してutilityを呼び出すことです。 xargsがすべての結果に対してutilityを呼び出すように強制する場合は、xargs -L1を使用して呼び出す必要があります。

xargsは、utilityに送信されるサブリストがARG_MAXよりも短いことを約束していることに注意してください(興味がある場合は、ARG_MAXを使用してgetconf ARG_MAXの現在の値を取得できます)。これにより、これらを回避できます。恐ろしい "引数リストを長くする"エラー。

46
Lars Tackmann

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の間にパイプがないことに注意してください。

10
DarenW
$ echo 'line1
> line2
> line3
> ...
> lineN ' | xargs cmd1 -a -b

結果は次のようになります。

$ cmd1 -a -b line1 line2 line3 ... lineN

xargsは、行数が大きくなりすぎると、cmd1 ...cmd1の複数の実行に分割します。

xargsは、位置引数としてstdin行を渡すことに関連する他の多くのタスクに使用できます。コマンドの複数のインスタンスを並行して実行するための xargs(1) の大文字の-Pオプションを見てください。

8

xargsは通常、引数をグループ化するために使用されるため、コマンドに多数の引数を渡したときに発生する「引数が多すぎます」というエラーは発生しません。

2
ennuikiller
#!/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つしかないため、正しい結果が得られます

2
Paul Creasey