web-dev-qa-db-ja.com

Perlのif(-f <filename>)は何をしますか?

私はこのコード行に出くわしました:

if( -f <filename> ) { ... }

-fは、ファイル名が存在するかどうかをテストしているようですが、わかりません。グーグルはこれまでのところ役に立ちませんでした( "-f"を付けるのはGoogleにとって困難です)と私のPerlの本もありません。

誰かアドバイスしてくれませんか?

27
doon

perlfunc を参照してください。

「ファイルテスト」を含むすべてのPerl組み込み関数をリストします。

-X FILEHANDLE
-X EXPR
-X DIRHANDLE
-X

どこ -Xは次のいずれかです。

-r: File is readable by effective uid/gid.
-w: File is writable by effective uid/gid.
-x: File is executable by effective uid/gid.
-o: File is owned by effective uid.

-R: File is readable by real uid/gid.
-W: File is writable by real uid/gid.
-X: File is executable by real uid/gid.
-O: File is owned by real uid.

-e: File exists.
-z: File has zero size (is empty).
-s: File has nonzero size (returns size in bytes).

-f: File is a plain file.
-d: File is a directory.
-l: File is a symbolic link.
-p: File is a named pipe (FIFO), or Filehandle is a pipe.
-S: File is a socket.
-b: File is a block special file.
-c: File is a character special file.
-t: Filehandle is opened to a tty.

-u: File has setuid bit set.
-g: File has setgid bit set.
-k: File has sticky bit set.

-T: File is an ASCII text file (heuristic guess).
-B: File is a "binary" file (opposite of -T).

-M: Script start time minus file modification time, in days.
-A: Same for access time.
-C: Same for inode change time (Unix, may differ for other platforms)
31
paxdiablo

Unixでは、ディレクトリには次のタイプのファイルを含めることができます。

  • プレーン(ファイルと見なすもの)
  • ディレクトリ
  • 名前付きパイプ
  • 名前付きソケット
  • ...

-f指定された名前がプレーンファイルであるファイルを参照しているかどうかをテストします。ファイルが存在しない場合はundef(エラーENOENT)を返します。ファイルは存在するがプレーンファイルではない場合(ディレクトリの場合など)は、他のいくつかのfalse値を返します。

-X演算子

7
ikegami
4
Jason Iverson

if (-f <filename> ) { ... }

質問を誤解したか、他の人が誤解しているようです。

まず、いくつかの仮定をしてみましょう。

  1. _-X_プレフィックスの単項演算子をすべてオーバーロードしていないと仮定します(すべての演算子か、どれもない)。

  2. また、_<>_サーカムフィックス反復演算子をオーバーロードしていないと仮定します。

上記の2つの条件が両方とも成立すると仮定すると、表記_<filename>_はscalar readline(*filename)を実行します。これは_$/_の値に依存し、その結果を後続の評価のためのファイルテスト演算子。通常はstat(2)を使用します。これは、本当に深いウィザードが含まれていない限り、これが機能するためにはfilenameという名前でファイルハンドルを開くのが最善であることを意味します。

__が_<$filename>_に対してもこれを行う場合、ただし_$filename_はfilenameのような直接的なハンドルではなく、間接的なハンドルです。この場合も、_$/_が尊重されます。関連付けられたファイルハンドルに適切なファイル名を使用することは、実際には私がすべての用語を実行することです。例えば:

_our $fn = "/etc/termcap";
open($fn, "<", $fn) || die "can't open $fn: $!";
_

このように、warnおよびdieメッセージは実際にファイルの名前を教えてくれます。例えば:

_while (<$fh>) {
     warn "oops" if whatever;
}
_

行番号と私がoopsしたファイルの名前を教えてくれます。

ここで、_<⋯>_のオペランドが、ブレースされていない許可された動的オブジェクト、つまり、ゼロ以上のドル記号が前に付いたベアワードのルールから逸脱している場合、反復演算子ではなく、ワイルドカードバースターです。これは、ワイルドカードがなくても当てはまります。これは、Perlの有名なRative of Dativesに違反している必要があります。

これは、ifとif iffilenameが、ゼロなどの先行ドル記​​号を含む正当な裸語ではないことを意味します—たとえば、_/etc/termcap_、_/tmp_、_*.[Cchy]_、_{,/usr}/bin/c?_、または_~/Documents_ —代わりに、_File::Glob::bsd_glob_関数のガイドでおなじみの古い畳み込み演算子が呼び出されます、適切な引数を指定すると、このような便利で一般的に使用される関数に期待するような結果が得られます。

上記の引用部分が実際に尋ねている種類の質問に対する回答を示す多くの例を次に示します。

_use v5.10;  # for the say feature, but not needed for conglobulation

if (-d <~joebob>                 ) { say "joebob has a home"                 }
if (-d <~joebob/.opera>          ) { say "joebob has an opera directory"     }
if (-d <~joebob/.ssh>            ) { say "joebob has an ssh directory"       }

if ($n = grep {-e} <~joebob/.*rc>) { say "joebob has $n RC files"            }

if (-f <~joebob/.exrc>           ) { say "joebob has a vi config file"       }
if (-f <~joebob/.profile>        ) { say "joebob has a sh profile"           }
if (-f <~joebob/.bashrc>         ) { say "joebob has a bash config script"   }
if (-f <~joebob/.cshrc>          ) { say "joebob has a csh config script"    }
if (-f <~joebob/.log{in,out}*>   ) { say "joebob has csh login/out scripts"  }

if (-S </tmp/.X*/X*>             ) { say "I smell an X11 socket"             }

if (-t STDIN && -t STDOUT        ) { say "smells pretty tty to me"           } 
_
2
tchrist