もし私がするなら
find . -exec echo {} +
すべてのパスを1行に印刷します。つまり、コマンドはecho
一度だけ実行されます。
しかし、それman find
によると
-exec command {} + ... the number of invocations of the command will be much less than the number of matched files. ...
場合によっては、コマンドが複数回実行されるようです。私は正しいですか?例えばください。
答え1
POSIXの定義find
-execユーティリティ_名前[パラメータ...] {} +ように:
注記の終わりは、<セミコロン>または<プラス記号>で句読点を付ける必要があります。 2 文字の「{}」のみを含む引数の直後にある <プラス記号> のみが、基本式の終わりを強調します。 <プラス記号>の他の用途は特別な用途と見なすべきではありません。基本式に<セミコロン>が付いている場合、ユーティリティはユーティリティ名各パス名に対して一度呼び出され、ユーティリティーが終了状態でゼロ値を返す場合、デフォルトのパスはtrueと評価する必要があります。 ㅏユーティリティ名またはディスカッション2文字の「{}」のみを現在のパス名に置き換える必要があります。もしユーティリティ名またはディスカッション文字列に「{}」の2文字が含まれているかどうかは実装によって定義されますが、「{}」の2文字のみが含まれるわけではありません。探すこれら2つの文字を置き換えるか、変更されていない文字列を使用してください。
基本式が<プラス記号>で区切られている場合、基本式は常にtrueと評価され、基本式が評価されるパス名はコレクションとして集計されます。実用的な事項ユーティリティ名 各集約パス名セットに対して一度に呼び出す必要があります。各呼び出しは、コレクションの最後のパス名が集計された後に開始する必要があります。探すユーティリティは、この基本の次のグループ(存在する場合)の最初のパス名を集計する前に終了しますが、呼び出しが他の基本の評価の前、途中、または後に発生するかどうかは指定されません。呼び出しが終了状態でゼロ以外の値を返す場合探す ユーティリティはゼロ以外の終了ステータスを返す必要があります。 2 文字の「{}」のみを含む引数は、集約されたパス名のセットで置き換える必要があり、各パス名は集計順序に従って呼び出しユーティリティに別々の引数として渡されます。複数のパス名のセットのサイズは、ユーティリティの実行によってシステムの{ARG_MAX}制限を超えないように制限する必要があります。。 2 文字 "{}" を含む引数が複数ある場合、動作は指定されません。
見つかったファイル名の長さがシステム設定を超えると、ARG_MAX
このコマンドが実行されます。
使用ARG_MAX
できる構成ファイルのインポート:
$ getconf ARG_MAX
2097152
一部のシステムでは、実際の値がARG_MAX
異なる場合があります。ここ詳細については。
答え2
POSIXシステムでは、新しいプロセスのパラメータリストには最大長があります。find
ファイルパスがこれより長い場合、実行は分割されます。 Linux の制限事項を確認するには、以下を使用してください。xargs --show-limits
(Mac OSでは使用できません。より良い選択肢を知っている人がいる場合は、ここにコメントを残してください。)
編集する:Gnoucの答えから直接盗んでパラメータリストの最大長を得るPOSIXメソッドはgetconf ARG_MAX
。しかし、私のMac OSコンピュータで実験を実行しましたが、find
この数字の半分以上が使用されているようです。これは、動作しているシステムではxargs --show-limits
最大引数の長さを使用しないと聞きましたが(この場合はその数の約半分を使用します)、その説明が見つからないという事実と一致します。理由。
編集2:find
各呼び出しでいくつかの引数が一緒に付いていることを確認する唯一の信頼できる方法は、次のように実行して実験するようです。
find / -exec echo {} + | wc -cl
各呼び出しにはfind
1行の出力があるので、echo
を使用して計算できますwc -l
。 edの合計バイト数echo
は反対の出力ですwc -c
。 1つずつ分割すると、コマンド呼び出しあたりの引数の平均バイト数が得られます(丸めのため少し低くなりますが、システムの平均パス長の約半分です)。