I would like to execute ls in a Perl program as part of CGI script.
For this I used exec(ls), but this does not return from the exec call.
Is there a better way to get a listing of a directory in Perl?
I would like to execute ls in a Perl program as part of CGI script.
For this I used exec(ls), but this does not return from the exec call.
Is there a better way to get a listing of a directory in Perl?
In order to get the output of a system command you need to use backticks.
$listing = `ls`;
However, Perl is good in dealing with directories for itself. I'd recommend using File::Find::Rule.
Exec doesn't return at all. If you wanted that, use system.
If you just want to read a directory, open/read/close-dir may be more appropriate.
opendir my($dh), $dirname or die "Couldn't open dir '$dirname': $!";
my @files = readdir $dh;
closedir $dh;
#print files...
exec does not give control back to the perl program. system will, but it does not return the results of an ls, it returns a status code. tick marks `` will give you the output of our command, but is considered by some as unsafe.
Use the built in dir functions. opendir, readdir, and so on.
I would recommend you have a look at IPC::Open3. It allows for far more control over the spawned process than system or the backticks do.
Everyone else seems stuck on the exec portion of the question.
If you want a directory listing, use Perl's built-in glob
or opendir
. You don't need a separate process.
Yet another example:
chdir $dir or die "Cannot chroot to $dir: $!\n";
my @files = glob("*.txt");
EDIT: Whoops! I thought you just wanted a listing of the directories... remove the 'directory' call to make this script do what you want it to...
Playing with filehandles is the wrong way to go in my opinion. The following is an example of using File::Find::Rule to find all the directories in a specified directory. It may seem like over kill for what you're doing, but later down the line it may be worth it.
First, my one line solution:
File::Find::Rule->maxdepth(1)->directory->in($base_dir);
Now a more drawn out version with comments. If you have File::Find::Rule installed you should be able to run this no problem. Don't fear the CPAN.
#!/usr/bin/perl
use strict;
use warnings;
# See http://search.cpan.org/~rclamp/File-Find-Rule-0.32/README
use File::Find::Rule;
# If a base directory was not past to the script, assume current working director
my $base_dir = shift // '.';
my $find_rule = File::Find::Rule->new;
# Do not descend past the first level
$find_rule->maxdepth(1);
# Only return directories
$find_rule->directory;
# Apply the rule and retrieve the subdirectories
my @sub_dirs = $find_rule->in($base_dir);
# Print out the name of each directory on its own line
print join("\n", @sub_dirs);