in reply to Looking to confirm a file against CVS as part of a loop
There are a few different ways to execute a program and capture its output. Which you want depends on what you're doing. In this case, it looks like you're using trusted data, so simply using qx (which is the generic form of backticks) would be the easiest. Here's a simple example:
for (glob "*.txt") { my $lsoutput = qx(ls -l $_); if ($lsoutput =~ /$ENV{USER}/) { print "File matches current username.\n"; } }
In your case, the filename variable is probably safe. But if it came from user input (say, through a web form), then using qx would be a security problem. That's because qx will run your external program from a shell, and the shell will interpret any meta-characters. So if someone gives the filename as "`rm -rf /home`", then the shell would see the backtick metacharacters, and execute the program between them. This is obviously a bad thing.
The other common way to read output from an external program is to use the piping form of open. Just for completeness, here's an equivalent snippet using open:
for (glob "*.txt") { open my $lsfh, "-|", 'ls', '-l', $_ or die "Cannot open 'ls': $!\n"; while (<$lsfh>) { if ($lsoutput =~ /$ENV{USER}/) { print "File matches current username.\n"; } } }
This one takes slightly more work to write, but one major benefit is safety. The list form of open avoids the metacharacter problem, because it doesn't call a shell at all.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Looking to confirm a file against CVS as part of a loop
by Seventh (Beadle) on Dec 20, 2004 at 19:23 UTC | |
by revdiablo (Prior) on Dec 20, 2004 at 20:30 UTC | |
by Seventh (Beadle) on Dec 21, 2004 at 15:44 UTC | |
by revdiablo (Prior) on Dec 21, 2004 at 17:30 UTC | |
by Seventh (Beadle) on Dec 22, 2004 at 17:58 UTC |