[JM:00111] Re: [POST:DP] GNU_findutils xargs.1

Back to archive index

Akihiro MOTOKI amoto****@gmail*****
2011年 1月 19日 (水) 23:56:18 JST


元木です。こんばんは。

> [JM:00091] などで「よくわからない、自信がない」などと書いた
> ところは、相変わらずよくわかっていません。ご意見をお寄せ
> いただけると、ありがたく思います。

ということで、コメントしてみます。

At Thu, 30 Dec 2010 14:03:13 +0900 (JST),
長南洋一 <cyoic****@maple*****> wrote:
> 
>   .BI "\-\-arg\-file=" file
>   .TP
>   .PD 0
>   .BI "\-a " file
>   .\"O Read items from 
>   .\"O .I file
>   .\"O instead of standard input.  If you use this option, stdin remains
>   .\"O unchanged when commands are run.  Otherwise, stdin is redirected 
>   .\"O from 
>   .\"O .IR /dev/null .
>   .\"O 
>   一連の項目を標準入力からではなく、
>   .I file
>   から読み込む。デフォルトでは、指定したコマンドを実行する際に標準入力が
>   .I /dev/null
>   に付け換えられるのだが、このオプションを使用すると、
>   標準入力が変更されることがない。
> 
> 「標準入力が変更されることがない」がいまいちわかりにくい気がします。
> 何かよい言い方がないでしょうか。

私もいい案が思い付きませんでした _o_

>   .BR "\-\-eof" [\fI=eof-str\fR]
>   .TP 
>   .PD
>   .BR \-e [ \fIeof-str\fR]
>   .\"O This option is a synonym for the 
>   .\"O .B \-E
>   .\"O option.  Use 
>   .\"O .B \-E
>   .\"O instead,
>   .\"O because it is POSIX compliant while this option is not.  If
>   .\"O \fIeof-str\fR is omitted, there is no end of file string.  If neither
>   .\"O .B \-E 
>   .\"O nor 
>   .\"O .B \-e 
>   .\"O is used, no end of file string is used.
>   このオプションは
>   .B \-E
>   オプションの同義語である。
>   .B \-E
>   の方を使ってほしい。理由は、そちらが POSIX に準拠しているのに対して、
>   こちらは準拠していないからだ。\fIeof-str\fR の部分が省略されると、
>   ファイル終了文字列が存在しないことになる。
>   .B \-E
>>   .B \-e
>   も指定しない場合、ファイル終了文字列は使用されない。
> 
> 原文のとおりに訳しているのですが、「存在しないことになる」のと
> 「使用されない」というのは、同じことでしょうか。

findutils-4.4.2 の xargs.c のソースを見てみたところ、両者は同じでした。

  static char *eof_str = NULL;

で定義される eof_str がファイル終端文字列へのポインタです。
オプションの解釈のところで、

  case 'E':		/* POSIX */
  case 'e':		/* deprecated */
    if (optarg && (strlen(optarg) > 0))
      eof_str = optarg;
    else
      eof_str = 0;
    break;

となっていて、eof_str を更新しています。
「eof-str の部分が省略されると」の場合は、else 側が該当するので、
eof_str に 0 が代入されます。

実際の判定は、

  #define EOF_STR(s) (eof_str && *eof_str == *s && !strcmp (eof_str, s))

のマクロで行われており、NULL でも 0 でも EOF_STR(s) は false になり、
両者は同じと言えます。

# char * に 0 を代入している、このコードは個人的には気持ち悪いです。

>   .B \-\-no\-run\-if\-empty
>   .TP
>   .PD
>   .B \-r
>   .\"O If the standard input does not contain any nonblanks, do not run the
>   .\"O command.  Normally, the command is run once even if there is no input.
>   .\"O This option is a GNU extension.
>   標準入力に空行しか含まれていなかったら、コマンドを実行しない。
>   通常では、入力が全くなかった場合でも、指定したコマンドが一回は
>   実行されるのだ。このオプションは GNU の拡張である。
> 
> 入力が空行だったときだけでなく、空白 (スペースやタブ) のみから
> なる行だったときも、コマンドを一回実行するようなので、
> 「標準入力に空白以外の文字が一つも含まれていない場合は、コマンドを
> 実行しない」に変更しようと思っています。わかりにくくなるかも
> しれませんが。

原文は nonblank と書かれていて、blank には空行だけでなく空白も
含まれるのではないでしょうか。空白だけの行の場合も nonblank ではないので、
有効な item は一つもありませんが、コマンドは一回実行されることになり、
原文の説明は正しいですね。

ここで言いたいのは、有効な要素が一つもない場合でもコマンドは一回は
実行される、ということで、「有効な要素が一つもない」ということを
does not contain any nonblank と表現しているのだと思います。

意見になっているでしょうか?

>   .BI \-s " max-chars"
>   .\"O Use at most \fImax-chars\fR characters per command line, including the
>   .\"O command and initial-arguments and the terminating nulls at the ends of
>   .\"O the argument strings.  The largest allowed value is system-dependent,
>   .\"O and is calculated as the argument length limit for exec, less the size
>   .\"O of your environment, less 2048 bytes of headroom.  If this value is
>   .\"O more than 128KiB, 128Kib is used as the default value; otherwise, the
>   .\"O default value is the maximum.  1KiB is 1024 bytes.
>   1 コマンドラインにつき最大 \fImax-chars\fR の文字を使用する。
>   この文字数には、指定したコマンドと \fIinitial\-arguments\fR、それに
>   各引き数文字列の終端を示すヌル文字も含まれる。指定できる値の上限は
>   システム次第であり、算出方法は、exec に対する引き数の最大長、
>   マイナス目下の環境のサイズ、マイナス 2048 バイトの余裕領域である。
>   もしその値が 128KiB 以上だったときは、デフォルトの値として 128KiB が
>   使用される。128KiB 未満だったときは、算出された上限がデフォルトの値になる。
>   1KiB は 1024 バイトである。
> 
> この訳は内容的に正しいでしょうか。
> 2048 bytes of headroom は「余裕領域」という訳でよいでしょうか。

内容は正しいと思います。

「算出方法は〜」の部分ですが、ちょっと読みにくかったので、
こんな案を考えてみました。いかがでしょうか。

  指定できる値の上限は、システム依存であり、
  exec に対する引き数の最大長から、その時点の環境のサイズと、
  余裕領域としての 2048 バイトを引いた値となる。

>   .nf
>   .B xargs sh -c 'emacs \(dq$@\(dq < /dev/tty' emacs
> 
>   .fi
>   .\"O Launches the minimum number of copies of Emacs needed, one after the
>   .\"O other, to edit the files listed on 
>   .\"O .BR xargs '
>   .\"O standard input.  This example achieves the same effect as BSD's 
>   .\"O .B -o 
>   .\"O option, but in a more flexible and portable way.
>   .\"O 
>   .\"O 
>   .\"O 
>   .B xargs
>   の標準入力でファイルをいくつか指定し、それを編集するために
>   Emacs のコピーを必要なだけ次々と立ち上げる。
>   この例は BSD の
>   .B -o
>   オプションと同じことを実現するが、柔軟性やどのシステムでも利用できる点で
>   勝っている。
> 
> 「Emacs のコピー」でよいですか。

exec 時に executable のデータがメモリ上に展開されますが、
これを「コピー」と言っているみたいですね。
「コピー」と明示的に言わなくてもいいかもしれません。

   xargs の標準入力からファイルのリストを受け取り、
   それらを編集するために、Emacs を必要最小限の数だけ次々と立ち上げる。

> portable を「移植性」と訳さず、「どのシステムでも利用できる」と
> くだいて訳しましたが、こう考えてよいでしょうか。

合っていると思います。
本当に感想ですが、
「勝っている」のところですが、ちょっと強過ぎるかなと感じました。
「こちらの方が、柔軟性があり、多くのシステムでも利用できる」
くらいでもいいかもしれません。

> 長いので引用しませんが、「バグ」セクションの「-I オプションを
> 使うと、標準入力から読み込まれた各行は内部的にバッファされる」
> のパラグラフは、訳文に自信がありません。大丈夫でしょうか。

大丈夫だと思います。

本文にあるように、
   somecommand | xargs -s 50000 echo | xargs -I '{}' -s 100000 rm '{}'
のようにコマンドを指定する場合でも、実際には somecommand が出力する
1行の最大の長さは分かっている必要がありますね。
この例の場合は、上限が 50000 バイトまで。

以上です。
-- 
Akihiro MOTOKI <amoto****@gmail*****>




linuxjm-discuss メーリングリストの案内
Back to archive index