パスが指定されていない場合、なぜ先頭の「./」が出力されるのですか?


13

パスが指定されていない場合、結果にfindつながる./結果を出力するのはなぜですか?

$ find
./file1
./file2
./file3

これを印刷しない理由は何ですか?

$ find
file1
file2
file3

回答:


16

理由 GNUの開発者がいるので、あなたがこれを見て、なぜです選んだのための「合理的な」行動を提供するためにパスが与えられていないときに。対照的に、POSIXはパラメーターがオプションであることを示していません。find find

findユーティリティは、再帰的にディレクトリ階層を降りなければならパスで指定された各ファイルに遭遇する各ファイルのオペランドのセクションで説明したプライマリで構成ブール式を評価し、。各パスオペランドは、後続のすべての<slash>文字を含め、提供されたままの状態で評価されます。階層内で遭遇する他のファイルのすべてのパス名は、現在のパスオペランド、現在のパスオペランドが1で終わっていない場合、およびパスオペランドに関連するファイル名の連結で構成され<slash>ます。相対部分には、ドットまたはドットドットコンポーネント、末尾文字、および<slash>パス名コンポーネント間の単一文字のみ。

それぞれの概要で違いを見ることができます。 GNUには(慣例どおり)角括弧で囲まれたオプション項目があります。

find [-H] [-L] [-P] [-D debugopts] [-Olevel] [starting-point...]
       [expression]

一方、POSIXはオプションであることを示していません。

find [-H|-L] path... [operand_expression...]

GNUプログラムでは、次のようにしftsfind.cます。

  if(空)
    {
      / *
       *一部のアクションが変更されるため、ここでは一時変数を使用します
       *一時的にパス。したがって、文字列定数を使用すると、
       *コアダンプを取得します。これの最も良い例は、
       * "find -printf%H"(注、 "find。-printf%H"ではありません)。
       * /
      char defaultpath [2] = "。";
      return find(デフォルトパス);
    }

"."簡単にするためにリテラルが使用されます。したがって、同じ結果が表示されます

find

そして

find .

なぜなら、与えられたパスが結果のプレフィックスとして使用されるからです(連結については上記を参照)。

少しの作業で、機能が最初に追加された時期を判断できました。1996年の「findutils」の最初の作成時に存在していました(参考文献を参照find.c)。

+  /* If no paths are given, default to ".".  */
+  for (i = 1; i < argc && strchr ("-!(),", argv[i][0]) == NULL; i++)
+    process_top_path (argv[i]);
+  if (i == 1)
+    process_top_path (".");
+
+  exit (exit_status);
+}

find 3.8の変更ログから、これは明らかに

Sat Dec 15 19:01:12 1990  David J. MacKenzie  (djm at egypt)

        * find.c (main), util.c (usage): Make directory args optional,
        defaulting to "."

11

通常、ファイルの後処理を行います。その場合、ファイル名をで開始することには大きな利点があります./。特に、ファイル名がで始まる場合、-後続のコマンドはそのファイル名とオプションを解釈できます。 ./それを避けます。

例として、これらのファイルがあるディレクトリを考えてみましょう。

$ ls
--link  --no-clobber

次に、ファイル名が./先頭なしで指定された場合、このコマンドがどのように機能するかを想像してください。

$ find -type f -exec cp -t ../ {} +

問題find自体を説明できます。上記と同じディレクトリで実行してみましょう。次の作品:

$ find ./*
./--link
./--no-clobber

次は失敗します:

$ find *
find: unknown predicate `--link'
Try 'find --help' for more information.

1
それは理にかなっている。しかし、その後、「。」を前に付けない理由があります。実行するときfind *
-nr

@nr良い点。何らかの歴史的な互換性のために、そのように動作することを期待しています。これが望ましくない動作である理由の例を回答に追加しました。
ジョン1024

3
一部のバージョンでは、ユーザーにパスの提供をfile 要求します(OS XでのBSDの検索など)。そのため、通常は次のように明示的に言う必要がありますfind . -type f ...。そこから、いくつかのバージョンのfind(GNU findなど)がデフォルトの.ままにし、他のすべてをそのままにすることは大きなステップではありません。
-ilkkachu

1
find *を表示しない理由.は、*すべてのファイルとフォルダーをリストするが、除外するためです.です。やるecho *1つまたは2つのファイルを含むディレクトリに、あなたはそれが表示されます .記載されていません。したがって、find *展開された各ファイルで動作します。find Desktop/ホームディレクトリから言った場合と同じです。出力は次のように表示されますDesktop/foo_bar.txt
Sergiy Kolodyazhnyy

1
@ John1024:MrigeshThomas Dickeyが質問に正しく答えたと思う。この回答は、そのfindように振る舞うのが便利な理由を述べています。findこのように動作するように設計された暗黙の主張をサポートするための信頼できる参照情報はありますかこの理由ますか?
G-マンは「元に戻すモニカ言う

4

findコマンドは検索するパス(複数可)が必要です。何も指定しない場合、現在のディレクトリ(.)が開始点として使用されます。同様に、パスなどを渡すと/tmp、それを開始点と見なします。したがって、結果。

現在のディレクトリの場合:

        $ find
or
        $ find .

output:
        ./file1
        ./file2
        ./file3

/tmpディレクトリの場合:

        $ find /tmp

output:
        /tmp/file4
        /tmp/file5

abc現在のディレクトリの下のディレクトリの場合:

        $ find abc

output:
        abc/file6
        abc/file7

現在のディレクトリの下に複数のディレクトリがある場合:

        $ find fu bar

output:
        fu/file10
        fu/file11
        bar/file8
        bar/file9

はい、find何かを検索するためのパスが必要であり、デフォルトで現在のディレクトリに設定されることに同意します。問題は、がと同じ./場合に先頭を出力する理由です。file.txt./file.txt
NR

1
その検索では「。」が追加されません。開始時に、「/ tmp」、「abc」、「。」のいずれであるかに関係なく、パスとして指定したものがすべて追加されます。それぞれすべての値を返します。
Mrigesh Priyadarshi

-2

パスを指定しない場合、findコマンドは${PWD}パスをパスと見なし、出力に出力します。ユーザーがパスを指定しなくても、find動作方法は変わりません。デフォルトでは、findは常にパスで機能します。


1
そうですか。しかし、あなたがそれを実行した場合/tmp、そうでは$PWDあり/tmpません./
NR

先行を表示する場合は/tmp、コマンドを実行しfind /tmpます。パスを指定しない場合は、常に現在のディレクトリになります./
MelBurslan

1
私は先を見ることを望んでいるわけではありません/tmp。それはできないこと$PWDです。
NR

私の謝罪${PWD}は間違った
言い回しでした-MelBurslan

2
いいえ、$ PWDを想定していません。出力を比較しfind .find $PWDそしてfind(あなたの検索がそれをサポートしている場合、パスなし)。
-ilkkachu
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.