Home > Archive > PERL Beginners > August 2005 > Directories into arrays, again.
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Directories into arrays, again.
|
|
| Daniel Kurtz 2005-08-26, 6:56 pm |
| OK, since everyone's making fun of my suggestion of using the output of
a shell command as a means of getting a directory listing into an array
<g>, please explain to me what's wrong with this code I'm trying, using
opendir and readdir:
opendir( DIR1, ".");
@before =3D readdir(DIR);
closedir(DIR1);
# Execute a command that backs up every file in the directory
# with a .bak extension.
opendir( DIR2, ".");
@after =3D readdir(DIR2);
closedir(DIR2);
Why does @after end up looking exactly like @before? Is there some
buffering going on here? And if so, how do I clear it?
daniel
| |
| Daniel Kurtz 2005-08-26, 6:56 pm |
| Sorry, obviously the code is supposed to read:
opendir( DIR1, ".");
@before =3D readdir(DIR1);
closedir(DIR1);
# Execute a command that backs up every file in the directory
# with a .bak extension.
opendir( DIR2, ".");
@after =3D readdir(DIR2);
closedir(DIR2);
It still doesn't work.
daniel
| |
| Daniel Kurtz 2005-08-26, 6:56 pm |
| From: Daniel Kurtz [mailto:dkurtz@olenick.com]=20[color=darkred]
buffering going on here? And if so, how do I clear it? <<<
Never mind, I figured it out. The file copying operation is another
shell operation (c'mon, I'm a newby, and I've only read as far as
perlopentut!) and the file handle needs to be closed before the second
opendir().
daniel
| |
| Wiggins d'Anconia 2005-08-26, 6:56 pm |
| Daniel Kurtz wrote:
> From: Daniel Kurtz [mailto:dkurtz@olenick.com]
>
>
> buffering going on here? And if so, how do I clear it? <<<
>
> Never mind, I figured it out. The file copying operation is another
> shell operation (c'mon, I'm a newby, and I've only read as far as
> perlopentut!) and the file handle needs to be closed before the second
> opendir().
>
> daniel
>
Ok, but that is why you are here to learn. And a reason why using a
shell command to copy a file is a bad idea. You didn't do any error
checking, so you didn't know where your problem was.
I assume you are using 'strict' and 'warnings'. If you aren't, you need
to be, and want to be. If you are reading a book, and it hasn't advised
you to do so, get a new book, most likely the Llama. If you are reading
the perldocs directly, then I would suggest getting the Llama as it will
make for much better use of your time.
opendir DIR1, '.' or die "Can't open directory for reading: $!";
In the above, you don't need the extra parens, there is no need to use
double quotes unless you are using interpolation and you weren't, so I
switched those to singles. And any operation that could fail should be
checked for failure, in the above case opendir will return nothing if it
fails, so we tack on a message, we include $! to learn *why* it failed.
my @before = readdir DIR1;
Declare our variables with the proper scope.
closedir DIR1;
# Execute a command that backs up every file in the directory
# with a .bak extension.
Here I would suggest using the File::Copy module, as it provides a
convenient 'copy' function which is all you are really doing. It is also
designed to be as portable as possible, and happens to be standard on
newer Perl versions.
use File::Copy;
foreach my $file (@before) {
if (-f $file) {
copy($file, "$file\.bak") or die "Can't backup file: $!";
}
}
opendir DIR2, '.' or die "Can't open directory for reading a second
time: $!";
my @after = readdir DIR2;
closedir DIR2;
No need for shell commands...
perldoc -f opendir
perldoc -f readdir
perldoc -f closedir
perldoc File::Copy
perldoc -f -e
perldoc strict
perldoc warnings
As an aside, if you must use a shell command you are better off sticking
with system, until you need the output which is provided by backticks,
only use the piped open form when you need to communicate with the
command you are running.
http://danconia.org
| |
| JupiterHost.Net 2005-08-26, 6:56 pm |
|
Daniel Kurtz wrote:
> Sorry, obviously the code is supposed to read:
Actually it should read:
use strict;
use warnings;
> opendir( DIR1, ".");
opendir DIR1, '.' or die "Could not open .: $!";
> @before = readdir(DIR1);
my @before = readdir DIR1;
> closedir(DIR1);
>
> # Execute a command that backs up every file in the directory
> # with a .bak extension.
Um, ok so you're wondering why there are no .bak files?
Then that would be the code to show :) although I bet
strict/warnings/and checking your open's (or die $!;) will show you what
is wrong :)
| |
| Daniel Kurtz 2005-08-26, 6:56 pm |
| Excellent points, all
From: Wiggins d'Anconia [mailto:wiggins@danconia.org]=20[color=darkred]
<<<
Well, the 'shell' and 'copy' association in this case is actually
something of a red herring. The point of this particular script is not
to copy files, it is to illustrate to a non-programmer an easy and dirty
way of executing a program and then capturing some 'results' for
analysis. In this case, the file copying batch program was used simply
because it produces readily verifiable results (either the .bak files
are there, one for each original file specified, or they're not.)
[color=darkred]
time: $!";
my @after =3D readdir DIR2;
closedir DIR2; <<<
Well, I boiled the script down to essentials before posting it,
including taking out some error handling (not on these particular
commands though.) However, in this particular instance, there were no
errors to trap. The *dirs worked correctly, they just weren't picking up
the changes made to the directory because those changes were not visible
to Perl until after the file handle to the shell was closed or otherwise
reset.
[color=darkred]
sticking with system, until you need the output which is provided by
backticks, only use the piped open form when you need to communicate
with the command you are running. <<<
I'm certain you're right. As it happens, in this particular instance the
script IS piping additional messages to the shell. Is open() the only
means of doing that?
daniel
| |
| Daniel Kurtz 2005-08-26, 6:56 pm |
| From: JupiterHost.Net [mailto:mlists@jupiterhost.net]=20
> # Execute a command that backs up every file in the directory # with a
> .bak extension.
[color=darkred]
Then that would be the code to show :) although I bet=20
strict/warnings/and checking your open's (or die $!;) will show you what
is wrong :) <<<
No, the .bak files are there. You can see them when you look at the
directory in Windows Explorer, or do a DIR from a command prompt. They
just aren't visible to the Perl script. Or weren't.=20
daniel
| |
| JupiterHost.Net 2005-08-26, 6:56 pm |
|
> Then that would be the code to show :) although I bet
> strict/warnings/and checking your open's (or die $!;) will show you what
>
> is wrong :) <<<
I see, however that is still the best practice to be in, especially when
asking for assistance since it catches 99.9% of little issues.
> No, the .bak files are there. You can see them when you look at the
> directory in Windows Explorer, or do a DIR from a command prompt. They
> just aren't visible to the Perl script.
Ok, that woudl be a good thign to explain innitially, sorry if you did
and I missed it :)
> Or weren't.
So its working now then?
What changed?
|
|
|
|
|