Подтвердить что ты не робот

Что делает if (-f <имя_файлa>) в Perl?

Я наткнулся на эту строку кода:

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

-f появляется, чтобы проверить, существует ли имя файла или нет, но я не уверен. Googling пока не помог (Google трудно "-f" ), и у меня нет книг Perl.

Кто-нибудь может посоветовать?

4b9b3361

Ответ 1

См. 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)

Ответ 2

В Unix каталоги могут содержать следующие типы файлов:

  • Обычная (что вы считаете файлом)
  • Каталог
  • Именованная труба
  • Именованный сокет
  • ...

-f проверяет, указывает ли предоставленное имя файл, который является простым файлом. Он вернет undef (ошибка ENOENT), если файл не существует, или некоторые другие ложные значения, если файл существует, но он не является обычным файлом (например, если это каталог).

- Операторы X

Ответ 4

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

Кажется, что либо я неправильно понял вопрос, либо все остальные имели.

Сначала давайте сделаем некоторые предположения.

  • Предположим, что вы не перегрузили все префикс -X унарных операторов (его либо всех, либо ни одного из них),

  • Давайте также предположим, что вы не перегрузили операцию итерации <>.

Предполагая, что оба этих двух значения, приведенные выше shoul, сохраняются, тогда обозначение <filename> будет делать scalar readline(*filename) - которое зависит от значения $/ - и затем передает этот результат обратно в оператор filetest для последующего оценка, обычно, но не обязательно в виде 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;
}

сообщит мне номер строки и имя файла, в котором я оопстед.

Теперь, если операнд <⋯> отклоняется от правил для разрешенных несвязанных дативных объектов, то есть голого слова с префиксом нуля или более знаков доллара, то это не оператор итерации, а шаблонный шаблон. Это верно даже без подстановочных знаков. Это просто должно нарушить знаменитое правило Datives Перл, а затем запускает альтернативный

Это означает, что тогда и только тогда, когда filename не является юридическим делом с нулевыми или более важными знаками доллара, такими как, например, /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"           } 

Ответ 5

Он проверяет, является ли объект, указанный <filename> равным файлом (в отличие от двоичного, или являющегося каталогом и т.д.).