Home > Net >  Unable to follow opendir syntax in Perl
Unable to follow opendir syntax in Perl

Time:09-17

I'm not a Perl user, so I only know the most rudimentary syntax, but I've inherited some scripts from a colleague for a data analysis pipeline that I'm trying to figure out.

Specifically, I can't understand how his perl scripts are locating the appropriate input/output directories using the following:

opendir DIR, "." or die

The way I've seen opendir used is along the lines of

opendir DIR, </yourpath> or die

I can't locate anything in the script to indicate what directory name is being accessed, so what is the "." syntax doing? I thought perhaps it just indicates to open the current directory, but that would presumably be

opendir DIR, './' or die

In any case, the program terminates without accessing the desired files, so I'm guessing this is the problematic line.

CodePudding user response:

Having seen that . is the current working-directory, here are a few facts of interest

  • This is not the directory where the program file resides. For that best use $FindBin::RealBin

  • A current working directory can change during the program run, by chdir or by libraries that are used. It may be different than expected if the program is started out of another program, or out of cron. In short, one should not assume what it is

  • The representation of it by the string . in many programming languages isn't a full language feature but more of an extra convenience, a courtesy of sorts; that's really an OS/filesystem thing. In a programming language it is incomplete and inconsistent, and may not be available when one might expect it. (Quick: can you save your current directory, so to be able to later come back to it after you've chdir-ed around, by using . in some way?)

    I use a library, like Cwd::cwd or Path::Tiny::cwd, to store the full-path working directory in a variable. (There are yet other ways to work with it in Path::Tiny)

  • To mention just in case: the opendir readdir combo returns barenames for files, with no path; so when querying from a directory other than the current one those aren't actual files. Remedies: either change working directory to the directory being read or prepend the path to each filename returned by readdir, so that filenames refer to existing files


If the program is in (the working directory) a_dir and it does opendir on ../other_dir, and then readdir returns file.txt -- there's no such file (in the current working directory, a_dir). The actual file, from where the program is, is ../other_dir/file.txt

Note, .., for the parent directory, is also defined, along with .

CodePudding user response:

Navigating in filesystem can be specified by absolute path, relative path, in reference to home directory, current directory or parent directory

  • Absolute path -- /usr/home/work/perl
  • Relative path -- ../bin/prog
  • Home directory -- ~ (or ~/), $HOME (environment variable)
  • Current working directory -- . (or ./)
  • Parent directory -- .. (or ../)

A few examples:

  • ~/bin/script (absolute because the shell expands the ~)
  • $HOME/bin/script (absolute because $HOME should be an absolute path)
  • /usr/local/bin/ldd (absolute)
  • /usr/sbin/tar (absolute)
  • script.pl (relative)
  • work/perl/script.pl (relative)
  • ./work/perl/script.pl (relative)
  • ./work/python/script.py (relative)
  • ../project/Makefile (relative)
  • ../book/perl.pdf (relative)

Reference: A beginner's guide to navigating the Linux filesystem

CodePudding user response:

This is not a Perl feature, but an OS one. In both Windows and unix systems, . refers to the process's current work directory.[1]

Each process has a CWD, which it inherits from its parent. It is the directory relative to which relative paths (those not starting with a directory separator) are resolved.

$ ls -l           # Defaults to the CWD.
total 0
-rw------- 1 ikegami ikegami 0 Aug 31 19:44 file

$ ls -l .         # The CWD.
total 0
-rw------- 1 ikegami ikegami 0 Aug 31 19:44 file

$ ls -l file      # `file` in the CWD.
total 0
-rw------- 1 ikegami ikegami 0 Aug 31 19:44 file

$ readlink -e .
/tmp/a

$ ls -l /tmp/a
total 0
-rw------- 1 ikegami ikegami 0 Aug 31 19:44 file

$ ls -l /tmp/a/file
total 0
-rw------- 1 ikegami ikegami 0 Aug 31 19:44 /tmp/a/file


  1. In Windows, there's a CWD for each drive. . alone refers to the CWD of the current drive.
  •  Tags:  
  • perl
  • Related