[32407] in Perl-Users-Digest
Perl-Users Digest, Issue: 3674 Volume: 11
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Mon Apr 23 18:09:26 2012
Date: Mon, 23 Apr 2012 15:09:08 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Mon, 23 Apr 2012 Volume: 11 Number: 3674
Today's topics:
Re: First Commercial Perl Program <ronaldljohnson@gmail.com>
Re: First Commercial Perl Program <ronaldljohnson@gmail.com>
Re: First Commercial Perl Program (Tim McDaniel)
Re: Optionally avoid AutoLoader <ben@morrow.me.uk>
Re: Optionally avoid AutoLoader <marc.girod@gmail.com>
Re: Optionally avoid AutoLoader <ben@morrow.me.uk>
Re: Perl on a Mac <justin.1203@purestblue.com>
record every backtick on STDOUT or some log file <muthuganesh.s@gmail.com>
Re: record every backtick on STDOUT or some log file <glex_no-spam@qwest-spam-no.invalid>
Re: record every backtick on STDOUT or some log file (Tim McDaniel)
Re: record every backtick on STDOUT or some log file <rweikusat@mssgmbh.com>
Re: record every backtick on STDOUT or some log file (Tim McDaniel)
Re: record every backtick on STDOUT or some log file <rweikusat@mssgmbh.com>
Re: record every backtick on STDOUT or some log file (Tim McDaniel)
Re: record every backtick on STDOUT or some log file <ben@morrow.me.uk>
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Mon, 23 Apr 2012 13:33:16 -0700 (PDT)
From: "tbb!/fbr!" <ronaldljohnson@gmail.com>
Subject: Re: First Commercial Perl Program
Message-Id: <5967447.113.1335213196491.JavaMail.geo-discussion-forums@pbbpo3>
On Monday, April 16, 2012 5:43:11 PM UTC-7, Ben Morrow wrote:
> Quoth Jim Gibson <jimsgibson@gmail.com>:
> > In article
> > <7095990.3.1334609061053.JavaMail.geo-discussion-forums@pbcva6>,
> > tbb!/fbr! <ronaldljohnson@gmail.com> wrote:
> > > my @bits=split(//,"$str");
> perldoc -q quoting
noted.
> > > unshift @bits, "\040";
> > split(//,$str) will handle a space character just like other
> > characters, so you don't need to add "\040" to the array, just put it
> > in the assignment.
> > > my $range=140;
> > > my $rndn=int(rand($range));
> > > my @nbits;
> > > my $count=0;
> > > while ($count < $rndn) {
> > > $nbits[$count]=@bits[rand @bits];
> > That should be:
> >
> > $nbits[$count] = $bits[rand @bits];
>
> ...and if you had been using 'warnings', perl would have told you so.
interesting enough, i always code under strict and warnings, and perl 5.10
on my Centos box doesn't complain with the way I've written it (does someone
know why? as I understand it's a scalar, but again, no warnings messages
pop up with: $nbits[$count]=@bits[rand @bits]; as opposed to:
$nbits[$count] = $bits[rand @bits];
> > > $count++;
> > > }
> >
> > You could also use this:
> > push( @nbits, $bits[rand @bits] ) for 1..$rndn;
> Or
> my @nbits = map $bits[rand @bits], 1..$rndn;
> Ben
You guys have been awesome here, and I am learning to code(?) a little more
efficiently in perl because of it, as well as everyone has been giving me
really good advice which I understand, and I haven't been flamed once! Very
cool.
I need to reread through this entire thread again, because there is some
learning here for me.
I'm working on another project now. It's a project where I read a line from
one file (the file has multiple lines) and then check to see if a certain
field from a second file matches. I already know how to do this with a nested
foreach reading in a line from the first file, and then a foreach (for) to
compare to all lines in the second file. That verbal explanation is how I
am doing it, and after much googling, it looks like everyone else does it that
way too. However, the datasets are HUGE (first file is 500m, the compare file
is 1tb). Is there a more efficient way to do this? For each line in the first
file, it has to go through every line in the 1tb file. And on and on. I have
been looking at references, but if I used references, it would only be a
'different' syntax for doing the same thing. How would I do some sort of
parallel processing on something like this. I did look at the threading model,
and thought that I would load say the first five lines and have a separate
thread for reading through that second file, but again, it seems like only
a workaround for the way I am already doing it. I hope this is making sense.
Anyways, thanks again for everything guys, and I still get a kick out of
Randal Schwartz replying here (comp me a Perl class?).
Thanks,
Ron
------------------------------
Date: Mon, 23 Apr 2012 13:43:50 -0700 (PDT)
From: "tbb!/fbr!" <ronaldljohnson@gmail.com>
Subject: Re: First Commercial Perl Program
Message-Id: <29312727.117.1335213830649.JavaMail.geo-discussion-forums@pbbpo3>
On Monday, April 2, 2012 1:50:46 PM UTC-7, Rainer Weikusat wrote:
> > use List::Util qw(shuffle);
> > my $str=3D'1234567890!@#$
> > %^&*()qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM_+{}|:"<>?~`-
> > =3D[]\;\',./1234567890!@#$
> > %^&*()qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM_+{}|:"<>?~`-
> > =3D[]\;\',./';
> > my @bits=3Dsplit(//,$str);
> > my @rnd=3Dshuffle(@bits);
> > my $stringer=3D"@rnd";
> > $stringer=3D~s/\s//g;
> > $stringer=3Dsubstr($stringer,0,140);
>=20
> $stringer =3D substr(join('', shuffle(grep { $_ !~ /\s/; } split(//, $str=
))), 0, 140);
>=20
> Especially, it makes more sense to throw the whitespace away before
> shuffling etc than to pass it through to the second-to-last stage of
> this 'processing pipeline' where it is deleted from the string.
In a post further down, you'll see I needed whitespace to be one of the ran=
dom characters chosen, so needed to modify the program (which is below). Bu=
t it's still an awesome piece of stringing stuff together. You've essential=
ly turned 5 lines into 1, and I look forward to the day I can see things th=
at way. I know, it will take time and experience, but it's still awesome to=
me, and why I chose this newsgroup to ask what I hope are thoughtful newbi=
e questions.
Thanks,
Ron
------------------------------
Date: Mon, 23 Apr 2012 21:32:13 +0000 (UTC)
From: tmcd@panix.com (Tim McDaniel)
Subject: Re: First Commercial Perl Program
Message-Id: <jn4hot$hl3$2@reader1.panix.com>
In article
<5967447.113.1335213196491.JavaMail.geo-discussion-forums@pbbpo3>,
tbb!/fbr! <ronaldljohnson@gmail.com> wrote:
> I'm working on another project now. It's a project where I read a
> line from one file (the file has multiple lines) and then check to
> see if a certain field from a second file matches. ... However, the
> datasets are HUGE (first file is 500m, the compare file is 1tb). Is
> there a more efficient way to do this?
I would tend to think that the efficient way is to see whether you can
use a decent database for this, like MySQL. A decent database system
is designed to allow fast lookups, so a few lines of SQL may allow you
to avoid having to re-implement indexing on your own.
--
Tim McDaniel, tmcd@panix.com
------------------------------
Date: Mon, 23 Apr 2012 15:57:50 +0100
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: Optionally avoid AutoLoader
Message-Id: <e87g69-l9m.ln1@anubis.morrow.me.uk>
Quoth Marc Girod <marc.girod@gmail.com>:
> On Apr 22, 11:55 pm, Ben Morrow <b...@morrow.me.uk> wrote:
>
> > I don't use the debugger.
>
> Well, I do. In fact, the debugger plays an important role in my using
> Perl.
> Anyway, I have to support users of the modules.
>
> > What happened when you tried it?
>
> I can load the .al files by name, but then, I cannot even read the
> code (hence not put breakpoints).
> I couldn't find a syntax to load any other file but the first
> (_Checkcs.al), which I load as 'MGi.pm'.
Did you try 'f _Checkcs.al' and so on, as I suggested? It seems to work
OK to me:
~/src/perl% perl -MPOSIX -de1
Loading DB routines from perl5db.pl version 1.33
Editor support available.
Enter h or `h h' for help, or `man perldebug' for more help.
main::(-e:1): 1
DB<1> POSIX::chdir;
Usage: POSIX::chdir(directory) at (eval 7)
[/usr/local/lib/perl5/5.12.4/perl5db.pl:638] line 2
DB<2> f chdir.al
Choosing ../../lib/POSIX.pm (autosplit into
../../lib/auto/POSIX/chdir.al) matching `chdir.al':
1 2 3 4 5 6 7 8 9 10
DB<3> b POSIX::chdir
DB<4> POSIX::chdir
POSIX::chdir(../../lib/POSIX.pm (autosplit into
../../lib/auto/POSIX/chdir.al):637):
637: usage "chdir(directory)" if @_ != 1;
DB<<5>> l
637==>b usage "chdir(directory)" if @_ != 1;
638: CORE::chdir($_[0]);
639 }
640
641 # end of POSIX::chdir
642: 1;
DB<<5>> c
Usage: POSIX::chdir(directory) at (eval 8)
[/usr/local/lib/perl5/5.12.4/perl5db.pl:638] line 2
DB<5> l 638
638: CORE::chdir($_[0]);
DB<6> l
639 }
640
641 # end of POSIX::chdir
642: 1;
DB<6> f -e
1==> 1
DB<7> f chdir.al
Choosing ../../lib/POSIX.pm (autosplit into
../../lib/auto/POSIX/chdir.al) matching `chdir.al':
1 2 3 4 5 6 7 8 9 10
DB<8> l 636
636 sub chdir {
DB<9> ^D
Note that the very first thing I did was *call* POSIX::chdir, so the .al
could be autoloaded.
Ben
------------------------------
Date: Mon, 23 Apr 2012 11:17:07 -0700 (PDT)
From: Marc Girod <marc.girod@gmail.com>
Subject: Re: Optionally avoid AutoLoader
Message-Id: <01985788-f949-4de4-9e72-10383435805c@d4g2000vbn.googlegroups.com>
On Apr 23, 3:57=A0pm, Ben Morrow <b...@morrow.me.uk> wrote:
> Did you try 'f _Checkcs.al' and so on, as I suggested? It seems to work
> OK to me:
Yes I did, and it didn't work for me...
> Note that the very first thing I did was *call* POSIX::chdir, so the .al
> could be autoloaded.
Well, I didn't do that, but I ran my code which requires all the
files:
ClearCase-Wrapper> perl -d wrapdebug -noautoload des -s lbtype:MG
Loading DB routines from perl5db.pl version 1.33
Editor support available.
Enter h or `h h' for help, or `man perldebug' for more help.
...
DB<1> c 145
main::(wrapdebug:145): my $status;
DB<2> f _Checkcs.al
Choosing blib/lib/ClearCase/Wrapper/MGi.pm (autosplit into blib/lib/
auto/ClearCase/Wrapper/MGi/_Checkcs.al) matching `_Checkcs.al':
1 2 3 4 5 6 7 8 9 10
At that point, I don't see the code.
Now indeed, if I exert it (not that exact piece but say the one I ran
on the debug line):
DB<8> c 73
main::one_cmd(wrapdebug:73): my $rc =3D eval { $cmd->(@ARGV) };
DB<9> s
main::one_cmd(wrapdebug:73): my $rc =3D eval { $cmd->(@ARGV) };
DB<9>
ClearCase::Wrapper::MGi::describe(blib/lib/ClearCase/Wrapper/MGi.pm
(autosplit into blib/lib/auto/ClearCase/Wrapper/MGi/describe.al):
2874):
2874: my $desc =3D ClearCase::Argv->new(@ARGV);
DB<9> v
2871 sub describe {
2872: use strict;
2873: use warnings;
2874=3D=3D> my $desc =3D ClearCase::Argv->new(@ARGV);
2875: $desc->optset(qw(CC WRAPPER));
2876: $desc->parseCC(qw(g|graphical local l|long s|short
2877 fmt=3Ds alabel=3Ds aattr=3Ds ahlink=3Ds ihlink=3Ds
2878 cview version=3Ds ancestor
2879 predecessor pname type=3Ds cact));
2880: $desc->parseWRAPPER(qw(parents|par9999=3Di family=3Di));
DB<9> b 2874
... I do get there, and it does work.
I believe that this is equivalent to your running CORE::chdir.
The problem is that this is a chicken and egg issue: if I know to
navigate to the code, I don't need the breakpoint...
It seems to me that the whole idea of breakpoints is to be able to
place them *before* I know whether I'll get there...
I already new to navigate to the code through the autoloader...
I have to think of it...
Is there any benefit at that stage?
Thanks again,
marc
------------------------------
Date: Mon, 23 Apr 2012 22:30:19 +0100
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: Optionally avoid AutoLoader
Message-Id: <b8ug69-sap.ln1@anubis.morrow.me.uk>
Quoth Marc Girod <marc.girod@gmail.com>:
> On Apr 23, 3:57 pm, Ben Morrow <b...@morrow.me.uk> wrote:
>
> > Did you try 'f _Checkcs.al' and so on, as I suggested? It seems to work
> > OK to me:
>
> Yes I did, and it didn't work for me...
>
> > Note that the very first thing I did was *call* POSIX::chdir, so the .al
> > could be autoloaded.
>
> Well, I didn't do that, but I ran my code which requires all the
> files:
>
> ClearCase-Wrapper> perl -d wrapdebug -noautoload des -s lbtype:MG
>
> Loading DB routines from perl5db.pl version 1.33
> Editor support available.
>
> Enter h or `h h' for help, or `man perldebug' for more help.
>
> ...
> DB<1> c 145
> main::(wrapdebug:145): my $status;
> DB<2> f _Checkcs.al
> Choosing blib/lib/ClearCase/Wrapper/MGi.pm (autosplit into blib/lib/
> auto/ClearCase/Wrapper/MGi/_Checkcs.al) matching `_Checkcs.al':
> 1 2 3 4 5 6 7 8 9 10
>
> At that point, I don't see the code.
You do, though :). The debugger is showing you the first ten lines of
that logical file, which are all empty. The #line declaration means the
actual code starts much further down.
> Now indeed, if I exert it (not that exact piece but say the one I ran
> on the debug line):
>
> DB<8> c 73
> main::one_cmd(wrapdebug:73): my $rc = eval { $cmd->(@ARGV) };
> DB<9> s
> main::one_cmd(wrapdebug:73): my $rc = eval { $cmd->(@ARGV) };
> DB<9>
> ClearCase::Wrapper::MGi::describe(blib/lib/ClearCase/Wrapper/MGi.pm
> (autosplit into blib/lib/auto/ClearCase/Wrapper/MGi/describe.al):
> 2874):
> 2874: my $desc = ClearCase::Argv->new(@ARGV);
> DB<9> v
> 2871 sub describe {
> 2872: use strict;
> 2873: use warnings;
> 2874==> my $desc = ClearCase::Argv->new(@ARGV);
> 2875: $desc->optset(qw(CC WRAPPER));
> 2876: $desc->parseCC(qw(g|graphical local l|long s|short
> 2877 fmt=s alabel=s aattr=s ahlink=s ihlink=s
> 2878 cview version=s ancestor
> 2879 predecessor pname type=s cact));
> 2880: $desc->parseWRAPPER(qw(parents|par9999=i family=i));
> DB<9> b 2874
>
> ... I do get there, and it does work.
> I believe that this is equivalent to your running CORE::chdir.
> The problem is that this is a chicken and egg issue: if I know to
> navigate to the code, I don't need the breakpoint...
Try this:
- open ClearCase/Wrapper/MGi.pm in your editor,
- find the 'describe' function in the __END__ section,
- note the line number where it starts,
- run the debugger, and type
f describe.al
l <line number in MGi.pm where &describe starts>
l
If you've loaded all the .als, I would expect you could also just use
l ClearCase::Wrapper::MGi::describe
which should take you to the right file and line directly.
> I have to think of it...
> Is there any benefit at that stage?
Any benefit in what? The AutoLoader? I would say not. If you want to do
delay-loading, there are simpler and less magical ways of doing it.
Ben
------------------------------
Date: Mon, 23 Apr 2012 11:47:28 +0100
From: Justin C <justin.1203@purestblue.com>
Subject: Re: Perl on a Mac
Message-Id: <0jof69-dib.ln1@zem.masonsmusic.co.uk>
On 2012-04-22, Torsten Jørgensen <info@stconinc.com> wrote:
> Does it understand #!/usr/bin/perl.
On my 10.5.8 it's /opt/local/bin/perl
> Can the Terminal run shell scripts.
Yes, I do it all the time (10.5.8).
Justin.
--
Justin C, by the sea.
------------------------------
Date: Mon, 23 Apr 2012 10:42:18 -0700 (PDT)
From: perlnewbie <muthuganesh.s@gmail.com>
Subject: record every backtick on STDOUT or some log file
Message-Id: <23446706.147.1335202938105.JavaMail.geo-discussion-forums@vbsf10>
Hi,
I got a Perl script from my colleague which I am going to run on my server.
This script is written to setup some folder structure and to create some us=
ers/group/permission/ownership. So, most part of the script uses backtick =
to call OS commands with some logic behind it. (my question is not about w=
hether backtick is good or bad).
I want to make a minimum changes to the script so that every backtick with =
variable interpolation (example: `cd $v` should be recorded as 'cd /var/tmp=
', same as executed by OS) is recorded on STDOUT/STDERR or to some log file=
.
I don't want to go and add print statement just before every backticks.
What should be the good minimum change (either internal change or thru some=
wrapper) with or without any modules would help my scenario?
I am looking for a summary of chmod, chown, mkdir OS commands executed by t=
his perl script.
Thanks.
------------------------------
Date: Mon, 23 Apr 2012 13:22:37 -0500
From: "J. Gleixner" <glex_no-spam@qwest-spam-no.invalid>
Subject: Re: record every backtick on STDOUT or some log file
Message-Id: <4f959dee$0$75671$815e3792@news.qwest.net>
On 04/23/12 12:42, perlnewbie wrote:
> Hi,
>
> I got a Perl script from my colleague which I am going to run on my server.
>
> This script is written to setup some folder structure and to create some users/group/permission/ownership. So, most part of the script uses backtick to call OS commands with some logic behind it. (my question is not about whether backtick is good or bad).
>
BTW: Backticks are generally not good, so rewrite it or have your
colleague rewrite it using the correct Perl functions: chdir,
chmod, etc..
> I want to make a minimum changes to the script so that every backtick with variable interpolation (example: `cd $v` should be recorded as 'cd /var/tmp', same as executed by OS) is recorded on STDOUT/STDERR or to some log file.
>
> I don't want to go and add print statement just before every backticks.
That's probably the easiest way to do what you want.
>
> What should be the good minimum change (either internal change or thru some wrapper) with or without any modules would help my scenario?
Could also change them into a sub call:
e.g.
`cd $v`;
run( "cd $v" );
sub run
{
my $cmd = shift;
print "Running: $cmd\n";
my $out = `$cmd`;
print "Output: $out\n";
}
------------------------------
Date: Mon, 23 Apr 2012 19:01:59 +0000 (UTC)
From: tmcd@panix.com (Tim McDaniel)
Subject: Re: record every backtick on STDOUT or some log file
Message-Id: <jn48v7$dfg$1@reader1.panix.com>
In article <4f959dee$0$75671$815e3792@news.qwest.net>,
J. Gleixner <glex_no-spam@qwest-spam-no.invalid> wrote:
>BTW: Backticks are generally not good, so rewrite it or have your
>colleague rewrite it using the correct Perl functions: chdir,
>chmod, etc..
Opinions may differ. I think that one should use tools that are
well-suited for the work. Personally, if the shell can do it
perfectly well, I'm as inclined to use the shell as not, especially if
it's useful that it affect only itself and not the Perl program.
E.g., maybe I want a bit of script to "cd '$dir' && munge foo.cfg
out.ppp" but I want the Perl program to stay where it is.
But I may be atypical, because I know how to do bullet-resistant
shell coding. It *is* harder to do; much easier to have
mkdir($dir,0777) or crash("my_mkdir: mkdir '$dir' failed: $!");
or use autodie (I think it is).
>Could also change them into a sub call:
I recommend that. I usually call it my_system. I usually have it
echo the final command line, and have a global debug boolean that
makes it only do the output without running it, and analyze $? and $!
and such. Maybe I have a log. The advantage of a sub is that you can
do anything.
I see that once I did
use English;
# Borrowed from the perlipc man page.
sub kidopen($@) {
my ($dir, @cmd) = @_;
my $pid;
my $sleep_count = 0;
if ($dir eq '<') {
$dir = '-|';
} elsif ($dir eq '>') {
$dir = '|-';
} else {
die "$0: internal: kidopen() has invalid direction $dir, ";
}
if ($dir eq '|-') {
open(KID, '|less');
return;
}
for (;;) {
$pid = open(KID, $dir);
last if defined $pid;
warn "$0: Cannot fork a child: $!\n";
die "$0: Too many attempts failed. Dying.\n"
if $sleep_count++ > 6;
sleep 10;
}
if ($pid) { # parent
# Return to caller to do something interesting.
} else { # child
exec @cmd or
die("$0: Cannot exec program: $!.\n",
" Program: @cmd");
# NOTREACHED
}
}
sub kidclose() {
$ERRNO = 0;
# print STDERR "=== DEBUG in kidclose\n";
close(KID) or
warn("$0: Child exited with code $CHILD_ERROR, ",
"errno ", 0+$ERRNO, ": $ERRNO.\n");
# print STDERR "=== DEBUG done in kidclose\n";
}
The advantage is that "exec @cmd" means that it will NOT be subject to
the vagarities of shell parsing, which is great if you have one
program with possible unusual arguments that you want not to be
violated by the shell, but really lousy if you want
cd $dir && cp * /scratch/wav
--
Tim McDaniel, tmcd@panix.com
------------------------------
Date: Mon, 23 Apr 2012 20:33:48 +0100
From: Rainer Weikusat <rweikusat@mssgmbh.com>
Subject: Re: record every backtick on STDOUT or some log file
Message-Id: <877gx6p7j7.fsf@sapphire.mobileactivedefense.com>
tmcd@panix.com (Tim McDaniel) writes:
> In article <4f959dee$0$75671$815e3792@news.qwest.net>,
> J. Gleixner <glex_no-spam@qwest-spam-no.invalid> wrote:
>>BTW: Backticks are generally not good, so rewrite it or have your
>>colleague rewrite it using the correct Perl functions: chdir,
>>chmod, etc..
>
> Opinions may differ. I think that one should use tools that are
> well-suited for the work. Personally, if the shell can do it
> perfectly well, I'm as inclined to use the shell as not, especially if
> it's useful that it affect only itself and not the Perl program.
> E.g., maybe I want a bit of script to "cd '$dir' && munge foo.cfg
> out.ppp" but I want the Perl program to stay where it is.
Perl supports fork. Also, when using the Perl functions, it is
possible to implement real error handling because the actual system
error codes are available.
------------------------------
Date: Mon, 23 Apr 2012 19:45:39 +0000 (UTC)
From: tmcd@panix.com (Tim McDaniel)
Subject: Re: record every backtick on STDOUT or some log file
Message-Id: <jn4bh3$lh4$1@reader1.panix.com>
In article <877gx6p7j7.fsf@sapphire.mobileactivedefense.com>,
Rainer Weikusat <rweikusat@mssgmbh.com> wrote:
>tmcd@panix.com (Tim McDaniel) writes:
>> In article <4f959dee$0$75671$815e3792@news.qwest.net>,
>> J. Gleixner <glex_no-spam@qwest-spam-no.invalid> wrote:
>>>BTW: Backticks are generally not good, so rewrite it or have your
>>>colleague rewrite it using the correct Perl functions: chdir,
>>>chmod, etc..
>>
>> Opinions may differ. I think that one should use tools that are
>> well-suited for the work. Personally, if the shell can do it
>> perfectly well, I'm as inclined to use the shell as not, especially if
>> it's useful that it affect only itself and not the Perl program.
>> E.g., maybe I want a bit of script to "cd '$dir' && munge foo.cfg
>> out.ppp" but I want the Perl program to stay where it is.
>
>Perl supports fork.
Quite so, but doing so reliably and well takes some effort, as shown
by "man perlipc".
>Also, when using the Perl functions, it is possible to implement real
>error handling because the actual system error codes are available.
Except that programs generally do their own error checking on their
own pretty well, like for "mv afile /unwritable", but you have to
implement that in Perl on your own, so that's actually an argument
*against* doing it in Perl.
Except, as I noted, if you're trying to do sophisticated quoting or
control in shell. It takes some knowledge and effort to do
bullet-resistant programming in either shell or Perl, and
unfortunately the skills needed for one often don't translate to the
other.
--
Tim McDaniel, tmcd@panix.com
------------------------------
Date: Mon, 23 Apr 2012 21:50:36 +0100
From: Rainer Weikusat <rweikusat@mssgmbh.com>
Subject: Re: record every backtick on STDOUT or some log file
Message-Id: <87sjfutboj.fsf@sapphire.mobileactivedefense.com>
tmcd@panix.com (Tim McDaniel) writes:
> Rainer Weikusat <rweikusat@mssgmbh.com> wrote:
>>tmcd@panix.com (Tim McDaniel) writes:
[...]
>>> if the shell can do it perfectly well, I'm as inclined to use the
>>> shell as not, especially if it's useful that it affect only itself
>>> and not the Perl program. E.g., maybe I want a bit of script to
>>> "cd '$dir' && munge foo.cfg out.ppp" but I want the Perl program
>>> to stay where it is.
>>
>>Perl supports fork.
>
> Quite so, but doing so reliably and well takes some effort, as shown
> by "man perlipc".
perlipc essentially only mentions fork as part of a daemonization
procedure. But that's not what you get with backticks. These just
instruct perl to fork, exec the shell and pass the command in
backticks as argument to it in a suitable way (which then causes the
shell to fork and exec the actual command, with the shell waiting for
the command and perl waiting for the shell. And any 'result' is only
available as text which needs to be interpreted/ parsed to get at the
actual data). And you can as well just fork the perl process and
execute the system calls changing the process state directly without
affecting the state of the parent process.
>>Also, when using the Perl functions, it is possible to implement real
>>error handling because the actual system error codes are available.
>
> Except that programs generally do their own error checking on their
> own pretty well, like for "mv afile /unwritable", but you have to
> implement that in Perl on your own, so that's actually an argument
> *against* doing it in Perl.
Minus output, the only result information perl gets from an external
command is generally "it worked" or "it failed" no matter what that
external command might have done. And this essentially makes it
impossible to implement an _error handling strategies_ in Perl.
------------------------------
Date: Mon, 23 Apr 2012 21:27:52 +0000 (UTC)
From: tmcd@panix.com (Tim McDaniel)
Subject: Re: record every backtick on STDOUT or some log file
Message-Id: <jn4hgo$hl3$1@reader1.panix.com>
In article <87sjfutboj.fsf@sapphire.mobileactivedefense.com>,
Rainer Weikusat <rweikusat@mssgmbh.com> wrote:
>tmcd@panix.com (Tim McDaniel) writes:
>> Rainer Weikusat <rweikusat@mssgmbh.com> wrote:
>>>Perl supports fork.
>>
>> Quite so, but doing so reliably and well takes some effort, as shown
>> by "man perlipc".
>
>perlipc essentially only mentions fork as part of a daemonization
>procedure.
perlipc in 5.8.8 mentions safe implementations of pipe open (which has
a fork implicitly behind the scenes) and backtick, defining "safe" as
"you can do it without the shell getting its grubby fingerprints on
the arguments".
To be fair, though, my Perl scripts don't usually have a problem with
chdir and such, so that aspect of using shell commands is not often of
use.
>>>Also, when using the Perl functions, it is possible to implement real
>>>error handling because the actual system error codes are available.
>>
>> Except that programs generally do their own error checking on their
>> own pretty well, like for "mv afile /unwritable", but you have to
>> implement that in Perl on your own, so that's actually an argument
>> *against* doing it in Perl.
>
>Minus output, the only result information perl gets from an external
>command is generally "it worked" or "it failed" no matter what that
>external command might have done. And this essentially makes it
>impossible to implement an _error handling strategies_ in Perl.
In practice, "it worked || it failed" has been good enough for me so
far. The shell programs I've called have been good enough about
reporting their errors for me to realize the underlying problem, and I
can't think of anything different to do depending on which failure
happened.
I'm not saying you're wrong, mind you. If you want to do a mkdir and
need to do different things based on which error happened, or you need
efficiency, then you have to call Perl's mkdir and look at the error
status. It's just that, for me, I haven't needed either, and
therefore things like
system('mkdir', '-p', $tmpdir) or die "cannot create '$tmpdir'.\n";
work for my purposes.
And I certainly don't want to re-implement
system('rm', '-rf', $dir) or die ...
in Perl.
--
Tim McDaniel, tmcd@panix.com
------------------------------
Date: Mon, 23 Apr 2012 22:20:05 +0100
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: record every backtick on STDOUT or some log file
Message-Id: <5ltg69-sap.ln1@anubis.morrow.me.uk>
Quoth perlnewbie <muthuganesh.s@gmail.com>:
>
> I got a Perl script from my colleague which I am going to run on my server.
>
> This script is written to setup some folder structure and to create some
> users/group/permission/ownership. So, most part of the script uses
> backtick to call OS commands with some logic behind it. (my question is
> not about whether backtick is good or bad).
You should use system() rather than backticks unless you are reading the
output of the command.
> I want to make a minimum changes to the script so that every backtick
> with variable interpolation (example: `cd $v` should be recorded as 'cd
> /var/tmp', same as executed by OS) is recorded on STDOUT/STDERR or to
> some log file.
>
> I don't want to go and add print statement just before every backticks.
>
> What should be the good minimum change (either internal change or thru
> some wrapper) with or without any modules would help my scenario?
Backticks are implemented with the 'readpipe' core function, which can
be overridden. Doing this is a little tricky, since perl doesn't want to
make it too easy to do by mistake; the easiest way is to create a little
module which uses Exporter, like this
package My::ReadPipe;
use warnings;
use strict;
use Exporter "import";
our @EXPORT = qw/readpipe/;
sub readpipe {
my ($cmd) = @_;
# You can do anything you like here
warn "Running [$cmd]";
# This calls the real readpipe function
return CORE::readpipe $cmd;
}
1;
Put this in a file My/ReadPipe.pm, somewhere in @INC. Now if you put
use My::ReadPipe;
at the top of your script, all the backticks will start warning.
You can override system in the same way (add a 'sub system', which calls
CORE::system, and add 'system' to @EXPORT), but you should be aware that
this will make the
system { "cmd" } @args;
form will stop working. Unfortunately there's no way to emulate that
form from Perl, but since I very much doubt you were using it that
doesn't matter very much :).
Ben
------------------------------
Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>
Administrivia:
To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.
Back issues are available via anonymous ftp from
ftp://cil-www.oce.orst.edu/pub/perl/old-digests.
#For other requests pertaining to the digest, send mail to
#perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
#sending perl questions to the -request address, I don't have time to
#answer them even if I did know the answer.
------------------------------
End of Perl-Users Digest V11 Issue 3674
***************************************