ellem has asked for the wisdom of the Perl Monks concerning the following question:

I would like to get the output of the dir command into a txt file. This would be simple from an NT shell script but I plan to incorporate this into a larger perl script.

I have this so far:


#!/usr/bin/perl -w use diagnostics ; use strict ; open (DIR, '>> c:\dir\dir.txt') || die "Can't open file; $!" ; while (<DIR>) { my $dir = `dir *.pl` ; write DIR ; } close DIR ;
lmoran@wtsgSPAM.com print "\x{263a}"

Replies are listed 'Best First'.
Re: Getting the output of a shell command
by davorg (Chancellor) on Jun 04, 2001 at 20:24 UTC

    It's really much easier than you think.

    #!/usr/bin/perl -w use diagnostics ; use strict ; open (DIR, '>> c:\dir\dir.txt') || die "Can't open file; $!" ; print DIR $_ foreach `dir *.pl`; close DIR;

    Update: Removed unnecessary comma from print statement.

    --
    <http://www.dave.org.uk>

    "Perl makes the fun jobs fun
    and the boring jobs bearable" - me

      Thanks yours worked!

      FYI the comma on line 7 (print DIR,) stopped the script from compiling.

      lmoran@wtsgSPAM.com print "\x{263a}"
Re: Getting the output of a shell command
by grinder (Bishop) on Jun 04, 2001 at 20:52 UTC

    Be careful what you ask for -- you may just wind up getting it. Are you really sure you want the exact output of the dir command, or do you just want the names of the files, or the date and/or the size as well. That is, do you expect to have to parse the output downstream to do something else with it?

    If this is the case, you are better off doing to internally in Perl, thereby saving the time it takes to launch off the sub-process as well as the time it takes to parse the results.

    For instance, if you want to gather the names of the files and their respective sizes, you could do something like:

    #! /usr/bin/perl -w use strict; my $dir = shift || '.'; opendir D, $dir or die "Cannot open dir $dir: $!\n"; my %size; while( defined( my $file = readdir(D) )) { # only makes sense to ask for the size of a file next unless -f $file; $size{$file} = (stat $file)[7]; } closedir D;

    And there you have it. If you want to save different information, look at the stat function stat. If you need to recurse directories (i.e. emulate dir's -s switch), take a look at File::Find. If you need to store more than one thing (e.g. the date and the size) then it would be a good time to learn about references (perldoc perlreftut and perldoc perlref).


    --
    g r i n d e r
Re: Getting the output of a shell command
by merlyn (Sage) on Jun 04, 2001 at 20:40 UTC
Re: Getting the output of a shell command
by the_slycer (Chaplain) on Jun 04, 2001 at 20:24 UTC
    open (DIR, '>> c:\dir\dir.txt') || die "Can't open file; $!" ; my $dir = `dir *.pl`; print DIR $dir;
    Should do the trick for you. $dir gets the whole output of dir (via backticks), print $dir to the outfile.
      sorry (didn't mean to imply that it didn't)yours worked too.

      lmoran@wtsgSPAM.com
      print "\x{263a}"
Re: Getting the output of a shell command
by snafu (Chaplain) on Jun 04, 2001 at 23:38 UTC
    Here is how I would do it:

    #!/usr/local/bin/perl -w ## ^^^^ change to your system needs. # for the best results in all your perl scripting # use strict. :) use strict; # edit these to match your needs. Remember # for dos, you will need to change the '/'s # to '\'s my $path = "/tmp"; my $file = "$ENV{HOME}/file.txt"; # open our descriptors. One for the directory # we need to read and one for the file in which # we will spool the directory information out to. opendir(DIR,$path) or die("Cannot open $path\n"); open(OP,">>$file") or die("Cannot open $file for writing\n"); # print out all files matching *.pl to file # descriptor OP (output) from reading the # DIR descriptor pointing back to $path. print OP join("\n",grep(/.*\.pl/,readdir(DIR))); # close our descriptors close(DIR); close(OP);
    ADDED:
    IMO, it is better to try and let the script do it all (unless you are writing a shell script (unix)or something similar) rather than calling system programs to do the work for you. It takes less machine resources to let the script (perl) do all the work for you.

    For the above example, you may need to change the $path and $file variables to work for your windows machine but the rest *should* work just fine.

    Edited by Snafu 1607 HRS EDT for completeness

    ----------
    - Jim

Re: Getting the output of a shell command
by BigJoe (Curate) on Jun 05, 2001 at 00:09 UTC
    Well the title shows that a quick
    my $output = `dir/b/x *.pl`;
    would do because of wanting to capture it. But on further reading your description I think if you want to use a module go with Merlyn's advise but you can always do it this way
    my $output = `dir/b/x *.pl > c:\dir\dir.txt`;
    $output will have nothing in it but it will create the file and populate it. But try and use the modules for portability.

    --BigJoe

    Learn patience, you must.
    Young PerlMonk, craves Not these things.
    Use the source Luke.
Re: Getting the output of a shell command
by blue_cowdawg (Monsignor) on Jun 04, 2001 at 23:32 UTC

    Why not:

    : : open FOUT,">> c:\dir\dir.txt" or die "couldn't open for writing: $!"; open PIPE,"dir |" or die "can't pipe!$!"; while ($line=<PIPE>){ chomp $line; # do something with it... printf FOUT "%s$/",$line; # or whatever } close FOUT; close PIPE;

    Peter L. BergholdSchooner Technology Consulting, Inc.
    Peter@Berghold.Netwww.berghold.net
    Unix Professional Services
Re: Getting the output of a shell command
by Vynce (Friar) on Jun 05, 2001 at 13:06 UTC

    i have to advise against use of backticks (`) on windows platforms; some commands may cause serious heartache. (i know you said this one works on NT, but unfortunately it's not a safe habit to get into.) As such, i'd re-evaluate what you really want and see if one of these solutions will do it or can be modified to do it.