Provided by: manpages-ja_0.5.0.0.20210215+dfsg-1_all
名前
xargs - 標準入力を読み込んでコマンドラインを作成し、それを実行する
書式
xargs [-0prtx] [-E eof-str] [-e[eof-str]] [--eof[=eof-str]] [--null] [-d delimiter] [--delimiter delimiter] [-I replace-str] [-i[replace-str]] [--replace[=replace-str]] [-l[max-lines]] [-L max-lines] [--max-lines[=max-lines]] [-n max-args] [--max-args=max-args] [-s max-chars] [--max-chars=max-chars] [-P max-procs] [--max-procs=max-procs] [--process-slot-var=name] [--interactive] [--verbose] [--exit] [--no-run-if-empty] [--arg-file=file] [--show-limits] [--version] [--help] [command [initial-arguments]] [訳注]: 見やすくするために、整理して単純化すると: xargs [options] [command [initial-arguments]]
説明
このマニュアルページは、GNU 版 xargs の使用法を説明している。 xargs は、標準入力から空白や 改行で区切られた一連の項目を読み込み (空白はダブルクォート、シングルクォート、バックスラッ シュによって保護できる)、 それを引き数にして、指定した command を 1 回以上実行する (デフォ ルトのコマンドは /bin/echo である)。このとき、ユーザが command に対して指定した引き数 (上 記書式の initial-arguments) があれば、 標準入力から読み込んだ一連の項目は、その後ろに追加 される。 標準入力における空行は無視する。 command のコマンドラインは、(-n や -L オプションが使用されていない場合は) システムが定めて いるコマンドラインの長さの限界に達するまで、長いものが作成される。 そして、指定された command が、入力項目のリストを一つ残らず処理するのに必要な回数だけ、呼び出される。 だか ら、おおむね、command が呼び出される回数は、入力項目の数よりも、ずっと少なくてすむわけだ。 このことは、たいていの場合、パフォーマンスを著しく向上させることになる。 なお、コマンドの 中には、都合がよいことに、並列的に実行できるものもある。-P オプションを参照していただきた い。 Unix ではファイル名に空白や改行を含むことが可能なので、 こうしたデフォルトの動作は、しばし ば問題を引き起こす。空白や改行を含むファイル名は、 xargs によって適切に処理されないの だ。そうした状況では、-0 オプションを使用した方がよい。そうすれば、その手の問題を回避する ことができる。 なお、-0 オプションを使う場合は、xargs の入力を生成するプログラムの方で も、区切りの指標に必ずヌル文字を使うようにする必要がある。 たとえば、そのプログラムが GNU find ならば、-print0 オプションでそれが可能だ。 指定したコマンドの実行が終了ステータス 255 で終了することがあれば、 xargs は即座に停止し て、それ以上入力を読み込まない。 また、このとき、エラーメッセージを標準エラーに表示する。
オプション
-0, --null 入力される一連の項目が、ホワイトスペース (空白や改行) ではなく、ヌル文字によって区 切られることになる。 また、引用符やバックスラッシュが特別な意味を持たなくなる (すな わち、あらゆる文字が文字通りに解釈される)。後述のファイル終端文字列も無効になり、 (xargs が作成するコマンドラインにおいて) 他の引き数と同じように扱われる。 このオプ ションは、入力される項目にホワイトスペース、引用符、バックスラッシュなどが含まれる 可能性がある場合に、役に立つ。 GNU find の -print0 オプションが生成する出力は、この モードに対応した入力になる。 -a file, --arg-file=file 一連の項目を標準入力からではなく、file から読み込む。 デフォルトでは、指定したコマ ンドが実行される際に、標準入力が /dev/null に付け換えられるが、このオプションを使用 した場合は、標準入力の付け換えが起こらない (訳注: 別の言い方をすると、指定したコマ ンドの実行中、デフォルトでは標準入力が使えなくなるので、たとえば、"rm -i" の出すプ ロンプトに応答できなくなるが、このオプションを使用した場合は、標準入力が使えるの で、応答できるということ)。 --delimiter=delim, -d delim 入力される一連の項目が、指定された文字によって区切られることになる。 指定される区切 り文字は、単一の文字でもよく、\n のような C 言語式のエスケープ文字でも、8 進数や 16 進数のエスケープコードでもよい。 8 進数や 16 進数のエスケープコードは、printf コマ ンドの場合と同様に解釈される。 マルチバイト文字には対応していない。入力を処理する 際、引用符やバックスラッシュは特別扱いされない。 すなわち、入力中のあらゆる文字 が、文字通りに解釈される。 -d オプションを指定すると、ファイル終端文字列は無効にな り、(xargs が作成するコマンドラインにおいて) 他の引き数と同じように扱われる。 入力 が、項目を改行で区切っているだけのような単純な構成の場合には、 このオプションを使っ てもよいが、ほとんどたいていの場合、なるべくなら、xargs の --null を使うように、出 力側のプログラムを組み立てる方が望ましい。 -E eof-str eof-str をファイル終端文字列として設定する。 ファイル終端文字列が入力中の 1 行とし て現れると、それ以後の入力は無視される。 -E も -e も指定しない場合、ファイル終端文 字列は使用されない。 (訳注: 原文には「入力中の 1 行として現れると (occurs as a line of input)」とあるが、実際の動作は「入力中に独立した 1 項目として現れると、それ以後 の入力は無視される」のようだ。) -e[eof-str], --eof[=eof-str] このオプションは -E オプションの同義語である。-E の方を使っていただきたい。 理由 は、そちらが POSIX に準拠しているのに対して、こちらは準拠していないからだ。 eof-str の部分が省略されると、ファイル終端文字列が存在しないことになる。 -E も -e も指定し ない場合、ファイル終端文字列は使用されない。 -I replace-str initial-arguments 中で文字列 replace-str が現れるすべての箇所を、標準入力から読み込 んだ名前で置き換える。 なお、標準入力中にクォートされていない空白があっても、それは 入力項目の区切りにはならない。 区切りの指標は改行文字だけになるのだ。-x と -L 1 が 自動的に設定される。 [訳注]: もう少し詳しく説明した方がよいだろう。普通、ユーザが xargs で実行するコマン ドに引き数 (それが initial-arguments である。上記書式を参照) を指定した場 合、標準入力から読み込まれた項目群は、initial-arguments の後ろにどんどん追 加されて行く。それに対して、-I replace-str オプションを使用した場合は、次の 二点が異なっている。 一つは、標準入力は改行で分割され、その 1 行 1 行が、コ マンド 1 回の実行につき 1 個づつ使用されること (それが -L 1 ということだ)。 もう一つは、その 1 行が 1 項目として扱われ (-L 1 を単独で使った場合とは、そ こが違う)、その 1 項目が、initial-arguments の後ろに追加されるのではな く、initial-arguments 中の文字列 replace-str が現れるすべての位置に埋め込ま れることだ。以下の例では、 "{}" が replace-str であり、"{} is {}" の部分が コマンド echo に対する initial-arguments である。-I の直後の空白は、あって もなくてもよく、replace-str は "{}" 以外の文字列でもよい。なお "{}" は クォートした方がよいかもしれない。 $ echo -e "AAA BBB\nCCC\nDDD" |xargs -I{} echo {} is {} AAA BBB is AAA BBB CCC is CCC DDD is DDD 入力項目を区切っているデリミタは改行だけであり、空白は項目の区切りとして機 能していないのがお分かりになるだろう。 別の言い方をすると、-I では、各行は 1 行全体が事実上クォートされてコマンドに渡される (注意: -L 1 にそんな作用は ない)。 従って、-I オプションを使えば、空白を含むファイル名を処理できるとい うことになる。 たとえば、カレントディレクトリに "nospace" と "have space" というファイルがあるとしよう。 $ ls |xargs file have: cannot open `have' (No such file or directory) space: cannot open `space' (No such file or directory) nospace: ASCII text $ ls |xargs -L1 file have: cannot open `have' (No such file or directory) space: cannot open `space' (No such file or directory) nospace: ASCII text $ ls |xargs -I{} file {} have space: UTF-8 Unicode text nospace: ASCII text -i[replace-str], --replace[=replace-str] このオプションは、 replace-str が指定されていれば、-Ireplace-str の同義語である。引 き数 replace-str が省略されていれば、-I{} と同じことになる。 このオプションは非推奨 である。-I を使った方がよい。 -L max-lines 1 コマンドラインにつき最大 max-lines 行の (空行ではない) 入力行を使用する。 入力行 の行末に空白文字が付いていると、その行は次の入力行に論理的に続いていることになる。 自動的に -x が指定される。 [訳注]: -n オプションとの違いに注意。 「行末に空白文字」云々については、以下の 3 番 目の例を他のものと比較していただきたい。 コマンドの実行回数がわかるよう に、echo に initial-argument を付けてみた (代わりに -t オプションを使っても よかったかもしれない)。 なお、デリミタをヌル文字にしたときや、--delimiter で指定したときの動作がどうなるかは、ご自分で試してみていただきたい。 $ echo AAA BBB CCC |xargs -L1 echo "line: " line: AAA BBB CCC $ echo -e "AAA\nBBB\nCCC" |xargs -L1 echo "line: " line: AAA line: BBB line: CCC $ echo -e "AAA \nBBB\nCCC" |xargs -L1 echo "line: " line: AAA BBB line: CCC -l[max-lines], --max-lines[=max-lines] -L オプションの同義語である。-L とは違って、max-lines という引き数を指定するかどう かは任意である。引き数 max-lines を指定しなかった場合は、デフォルトの 1 が使用され る。POSIX 規格では -L の方を使うことになっているので、-l オプションの使用はお勧めで きない。 -n max-args, --max-args=max-args 1 コマンドラインにつき最大 max-args 個の引き数を使用する。 作成されたコマンドライン が、コマンドライン長の上限を超過する場合は (-s オプション参照)、max-args より少ない 引き数が使用されることになる。 ただし、-x オプションが指定されているときは別で、そ の場合は xargs が終了する。 -P max-procs, --max-procs=max-procs 同時に実行するプロセスの最大数を max-procs にする。デフォルトは 1 である。 max-procs が 0 だと、xargs はできるだけ多くのプロセスを同時に実行しようとする。 -P オプションには、-n か -L オプションを併せて使用するべきだ。 さもないと、おそらく exec 関数がたった一回しか実行されないことになるだろう。 xargs の実行中に、そのプロ セスに SIGUSR1 シグナルを送れば、同時に実行するコマンドの数を増やすことができる。 また、SIGUSR2 シグナルを送れば、その数を減らすことができる。 ただし、実装が決めてい る上限を越えて増やすことはできないし (上限は --show-limits を使えば、知ることができ る)、1 より少なくすることもできない。 xargs は、実行しているコマンドを終了させるわ けではない。 実行数を減らすように命じられたときは、単に現在動いているコマンドが二つ 以上終了するのを待ち、 それから別のコマンドを開始するのである。 注意していただきたいが、共有リソースに対する並列アクセスをきちんと管理するのは、呼 び出されるプロセス側の問題だ。 たとえば、複数のプロセスが標準出力に書き出そうとした 場合、出力は不定の順番で生成されることになる (だから,混じり合ってしまう可能性が高 い)。そうならないためには、プロセス同士が何らかの形で協力し合う必要がある。 ロッキ ング・スキームのようなものを使うのは、そうした問題を避けるための一方法である。 た だ、一般に、ロッキング・スキームの使用は、適切な出力を保証してはくれるものの、パ フォーマンスを低下させることになる。 パフォーマンスが落ちるのが嫌ならば、単純に各プ ロセスがそれぞれ別の出力ファイルを作るように (あるいは、別のリソースを使うように) すればよい。 -p, --interactive コマンドライン 1 行ごとに、実行するかどうかをユーザに尋ねるプロンプトを出し、端末か ら 1 行読み込む。コマンドラインを実行するのは、 返答が `y' または `Y' で 始まるとき だけである。自動的に -t が指定される。 --process-slot-var=name 複数の子プロセスを同時実行しているとき、その各子プロセスで環境変数 name にユニーク な値をセットする。値は、子プロセスが終了すると、再利用される。 この機能は、たとえ ば、初歩的な負荷分散スキームで利用できる。 -r, --no-run-if-empty 標準入力に空白しか含まれていない場合は、指定したコマンドを実行しない。 通常では、入 力が全くない場合でも、コマンドが一回は実行されるのである。 このオプションは GNU の 拡張である。 -s max-chars, --max-chars=max-chars 1 コマンドラインにつき最大 max-chars の文字を使用する。 この文字数には、指定したコ マンドと initial-arguments、それに各引き数文字列の終端を示すヌル文字も含まれる。 指 定できる値の上限は、システム次第であり、exec 関数に対する引き数の最大長から、現在の 環境のサイズと 2048 バイトの余裕領域を引いたものである。もしその値が 128KiB 以上 だったときは、デフォルトの値には 128KiB が使用される。 128KiB 未満のときは、算出さ れた上限がデフォルトの値になる。 1KiB は 1024 バイトである。制限がより厳しい場合で も、xarg は自動的にそれに対応する。 --show-limits コマンドライン長の上限を表示する。コマンドライン長の上限は、 オペレーティングシステ ム、xargs が設定したバッファサイズ、それに -s オプションによって決まる。xargs にコ マンドライン長の上限の表示以外をさせたくなかったら、 入力を /dev/null からパイプで xargs に渡してやればよい (さらに --no-run-if-empty を指定した方がよいかもしれな い)。 -t, --verbose 実行する前に、コマンドラインを標準エラー出力に表示する。 -x, --exit 作成されたコマンドラインがコマンドライン長の上限を超過していたら (-s オプションを参 照)、終了する。 --help xargs のオプションについて簡単に説明し終了する。 --version xargs のバージョン番号を表示して、終了する。
用例
find /tmp -name core -type f -print | xargs /bin/rm -f /tmp ディレクトリ以下に core という名前のファイルを捜して、それを消去する。 改行や空白を含 むファイル名があると、正しく動作しないので、注意すること。 find /tmp -name core -type f -print0 | xargs -0 /bin/rm -f /tmp ディレクトリ以下に core という名前のファイルを捜して、それを消去する。 ファイル名の処 理に当たっては、ファイル名やディレクトリ名に空白や改行が含まれていても、適切に扱われるよう にしている。 find /tmp -depth -name core -type f -delete /tmp ディレクトリ以下に core という名前のファイルを捜して、それを消去する。 上の例よりもこ ちらの方が効率的である (なぜなら、 rm を実行するために fork(2) と exec(2) を使わないですむ し、そもそも、 xargs のプロセスを必要としないから)。 cut -d: -f1 < /etc/passwd | sort | xargs echo システムの全ユーザを列挙した簡潔なリストを生成する (訳注: 要するに、改行ではなく、空白で区 切られたユーザ名のリストを作るということ)。 xargs sh -c 'emacs "$@" < /dev/tty' emacs xargs の標準入力からファイルのリストを受け取り、Emacs を必要なだけ次々と実行して、ファイル を編集する。この例は BSD の -o オプションと同じことを実現するが、こちらの方が柔軟性があ り、多くのシステムで利用できる。
終了ステータス
xargs の終了ステータスは以下のとおりである。 0 成功した。 123 指定したコマンドの実行が 1-125 のステータスで終了した。 124 指定したコマンドが 255 のステータスで終了した。 125 指定したコマンドがシグナルによって kill された。 126 指定したコマンドが実行できない。 127 指定したコマンドが見つからない。 1 上記以外のエラーが起きた。 128 以上の終了ステータスは、致命的なシグナルのせいでプログラムが止まったことを示すため に、シェルが使用している。
規格への準拠
GNU xargs version 4.2.9 以来、ファイルの論理的な終端を示す指標 (a logical end-of-file marker) を持たないのが、xargs のデフォルトになっている。このことは POSIX (IEEE Std 1003.1, 2004 Edition) で認められている。 -l や -i オプションは 1997 年版の POSIX 規格には存在するが、 2004 年版の POSIX 規格には存 在しない。従って、それぞれ -L や -I の方を使うべきである。 POSIX 規格は、実装に当たって、exec 関数に対する引き数のサイズに上限を設けることを認めてい る。 そして、その上限は、環境のサイズも含めて、少なくとも 4096 バイトあればよいことになっ ている。 移植性のあるスクリプトを書こうと思ったら、これより大きいサイズを当てにしてはいけ ない。 もっとも、実際の上限がそんなに小さい実装に、筆者は出会ったことがないけれど。 --show-limits オプションを使えば、使用中のシステムで有効な実際の上限を知ることができる。
関連項目
find(1), locate(1), locatedb(5), updatedb(1), fork(2), execvp(3), kill(1), signal(7), xargs については、充実した関連文書が Texinfo マニュアルの形で保守されている。 info と xargs プログラムが、御使用のサイトできちんとインストールされているならば、 info xargs とコ マンドを打ち込むことで、詳細なマニュアルが読めるはずだ。
バグ
-L オプションと -I オプションを組み合わせても、うまく行かない。 組み合わせて使えた方がよい のかもしれないが。 [訳注]: -I オプションの説明にあるように、-I replace-str を指定すると、 -L 1 が自動的に設定 される。だから、ここで言っているのは、現状では -L 2 や -L 3 を -I と一緒に使って も、期待する結果は得られないということだろう。 xargs を安全に使うことは不可能である。なぜなら、入力されるファイル名のリストを生成する時間 と xargs が実行するコマンドがそれを使用する時間との間には、必ず時間差があるからだ。 も し、他のユーザがシステムにアクセスすることができれば、 そのユーザはこの時間の隙間にファイ ルシステムを操作して、xargs が実行するコマンドの動作を、こちらが意図していないファイルに無 理矢理向けることができる。 この問題や、これに関連する問題については、 findutils に含まれる Texinfo 文書の「Security Considerations」という章でもっと細かく論じているので、 そちらを参 照していただきたい。なお、find の -execdir オプションは、より安全な方法として xargs の代わ りに使用できることが多い。 -I オプションを使うと、標準入力から読み込まれた各行が内部的にバッファされる。 それは、-I オプションを付けて使ったとき、xargs が受け入れる入力行 1 行の長さに上限があるということ だ。この制限を回避するには、-s オプションを使って、xargs が使用するバッファ空間のサイズを 増やしてやればよい。 さらに、xargs をもう一つ実行すれば、長すぎる行の出現を確実に避けるこ とができる。たとえば、 somecommand | xargs -s 50000 echo | xargs -I '{}' -s 100000 rm '{}' この例では、xargs の最初の実行には、入力行の長さの上限がない。 -I オプションを使っていない からである。 xargs の二番目の実行には、そうした上限があるが、処理できる以上の長さの行に絶 対に出会わないようになっている。 これが理想的な解決法だというのではない。むしろ、 -I オプ ションによって入力行の長さに上限ができない方がよいのであり、 だからこそ、この問題を「バ グ」セクションで論じているのである。 なお、この問題は find(1) の出力では起きない。find は 1 行に 1 ファイル名しか出力しないからだ。 バグ報告の最善の方法は、http://savannah.gnu.org/bugs/?group=findutils にある書式を使用する ことである。そうすれば、問題解決の進行状態を追うことができるからだ。 xargs(1) や findutils パッケージ全般についてのその他のご意見は、 bug-findutils メーリングリストにお出しになれば よい。 メーリングリストに参加するには、bug-findutils-request@gnu.org 宛に E メールを送って いただきたい。
翻訳について
この翻訳は findutils-4.6.0 所収の xargs.1 の翻訳である。 お手元の findutils は、もっと新し いバージョン、たとえば 4.7.0-git になっているかもしれない。だが、4.7.0 は開発中の版なの で、manpage も変化し続けており、現時点で最新の 4.7.0 のマニュアルを翻訳しても、お手元の英 語マニュアルとは内容が微妙に違うかもしれないのだ。 バージョンが同じ 4.7.0 なのに、それでは 紛らわしい。そこで、あえて現在の安定版、4.6.0 のマニュアルを底本にした。 ご参考までに書いておくと、2017/06/09 以降の 4.7.0-git の xargs には、-o (--open-tty) とい うオプションが追加されている。4.7.0-git の man xargs によれば、「コマンドを実行する前 に、子プロセスで標準入力を /dev/tty として再オープンする」というものである。そうした最近の バージョンでは -o オプションを使えば、たとえば "find . -name '*.txt~' | xargs -o rm -i" と いったことが可能になるようだ。失敗しても困らないファイルでお試しいただきたい。 (2018/03/03) XARGS(1)