[6507] in Perl-Users-Digest
Perl-Users Digest, Issue: 132 Volume: 8
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Mon Mar 17 16:27:22 1997
Date: Mon, 17 Mar 97 13:00:19 -0800
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, 17 Mar 1997 Volume: 8 Number: 132
Today's topics:
[Q] fast transpose (Matthew Pressly )
Re: Can 5.01 handle 4.0.1.8 scripts? <axvu@netmail.mnet.uswest.com>
Re: continuation-passing and tail-recursion <vladimir@cs.ualberta.ca>
getting IP address with gethostbyaddr ? <ling@esbs.u-strasbg.fr>
Re: getting IP address with gethostbyaddr ? <flg@vhojd.skovde.se>
Re: How do I make the <STDIN> invisible? <Jan.Krynicky@st.ms.mff.cuni.cz>
Re: learning perl <chuckr@ptw.com>
Re: matching whitespace? <axvu@netmail.mnet.uswest.com>
Re: matching whitespace? <tchrist@mox.perl.com>
Re: Pattern matching on stream (Matthew H. Gerlach)
Re: Pattern matching on stream <fawcett@nynexst.com>
perl -w <rick.tan@Eng.Sun.COM>
perl and cgi Bob_Franklin@illinova.com
Perl Compiler (Steven Sajous)
Perl for NT ***Help**** <jont@uunet.pipex.com>
Re: Q: How can I read the full pathname <rra@cs.stanford.edu>
Signaling a child process (Kim Lewall)
Re: sourcing (bash) config files within perl <seay@absyss.fr>
Re: Splitting a multi line string <flg@vhojd.skovde.se>
Re: What language do Perl REs recognize? <vladimir@cs.ualberta.ca>
Digest Administrivia (Last modified: 8 Mar 97) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: 17 Mar 1997 18:37:46 GMT
From: mattp%oakhill@sps.mot.com (Matthew Pressly )
Subject: [Q] fast transpose
Message-Id: <5gk31q$hlu@newsgate.sps.mot.com>
I've written a transpose script in perl that pads a text file so that all
lines are equal length, and then transposes it so that rows become columns,
and vice versa. For large files that are taller than wide (around 100
chars per line and 30000 lines), this script is about 10 times as slow as
an equivalent routine written in C. I remember reading a claim that it
should be possible to write perl scripts that are at worst a factor of 'e'
(2.71828...) times slower than their C equivalents, but I've made all the
optimizations I can think of on the perl script and have not been able to
get it any faster than about 1/10th the speed of the C equivalent. Does
anyone have ideas on how to speed this up? I would much prefer to use a
perl version of this because it is a subtask of a much larger program, and
the perl version is much simpler than the C version. [Included below are
the perl ptranspose source, C tranpose.c source, perl source for randline,
which builds "random" text files of specified width and length, and results
obtained running these on a Sparc20].
Also, in general, I've found that I can get acceptable performance from
Perl in most cases except those which, like the transposition problem,
require large amounts of individual character manipulation in large files.
Are there any general hints, other than those in the Camel Perl book, about
improving the speed in those situations?
Here is the perl source code (ptranspose):
--------------------------- BEGIN INCLUDE --------------------
#! /usr/local/bin/perl
### Perl transpose script
#
@arr = <>;
$len = 0;
### Find length of longest line, and remove newlines ###
print STDERR "Finding longest line\n";
foreach (@arr) {
chomp;
$len = length($_) if length($_) > $len;
}
### Lengthen short lines ###
print STDERR "Shortening long lines\n";
foreach (@arr) {
s/\n//g;
$_ .= ' ' x ($len - length($_));
}
print STDERR "Transposing\n";
### Older, slower way of doing transposition ###
#for($j=0; $j<=$len; $j++) {
# $line = "";
# for($i=0; $i<= $#arr; $i++) {
# $line .= substr($arr[$i], $j, 1);
# }
# print $line,"\n";
#}
undef (@output);
for ($i = 0; $i <= $len; $i++) {
$new_line = "";
grep($new_line .= substr($_, $i, 1), @arr);
print "$new_line\n";
}
--------------------------- END INCLUDE --------------------
Here is the C source code (transpose.c compiled to transpose):
--------------------------- BEGIN INCLUDE --------------------
#include <stdio.h>
#include <malloc.h>
/*
** Read a text file on stdin. Transpose it, so that rows become columns,
** and write it back out.
*/
#define BUFFSIZE 5000
char **build_linestarts();
main(argc, argv)
int argc; char **argv;
{
char *buffer, *linebuf, **linestarts;
char *p, *q;
FILE *fin;
long fsize = 0;
int rval = 0;
int nlines;
int offset = 0;
int i;
int done = 0;
if (argc == 0) {
fprintf(stderr, "usage: transpose inputfile\n");
exit(1);
}
if ((fin = fopen(argv[1], "r")) == NULL) {
fprintf(stderr, "ERROR: cannot open '%s' for input: ", argv[1]);
perror(NULL);
exit(1);
}
fseek(fin, 0L, 2);
fsize = ftell(fin);
fseek(fin, 0L, 0);
buffer = (char *) malloc((unsigned) fsize + 2);
if ((rval = fread(buffer, fsize - 1, 1, fin)) <= 0) {
fprintf(stderr, "ERROR reading input file: fread returns %d\n", rval);
perror(NULL);
exit(1);
}
*(buffer + fsize + 1) = 0; /* Add null termination */
fsize = strlen(buffer);
if (*(buffer+fsize-1) != '\n') {
*(buffer+fsize) = '\n'; /* Add carriage return */
*(buffer+fsize+1) = '\0'; /* And terminate the string */
}
nlines = number_lines(buffer); /* Longest line this many chars */
linebuf = (char *) malloc((nlines + 1) * sizeof(char));
linestarts = build_linestarts(buffer, nlines);
/******** Generate the output stream *************/
done = 0;
offset = 0;
while(!done) {
done = 1;
q = linebuf;
for(i=0; i<nlines ; i++) {
p = linestarts[i] + offset;
/* printf("%d %d %ld\n", i, offset, p); */
if (*p == 0) {
*q++ = ' '; /* Space fill if end of string */
} else if (p >= linestarts[i+1]) {
*q++ = ' '; /* Space fill if past end of string */
} else { /* Copy the character */
*q++ = *p;
done = 0;
}
}
*q++ = 0;
puts(linebuf);
offset++;
}
fprintf(stderr, "Number of lines in file: %d\n", nlines);
}
/*
* Return an array of pointers to the start of
* each line. Also convert carriage returns to
* NULL characters, so that the array is decomposed
* into individual strings.
*/
char **build_linestarts(p, nlines)
char *p;
int nlines;
{
char **linestarts, **lstmp;
char *q;
int i = 0;
fprintf(stderr, "Building linestarts...\n");
lstmp = linestarts = (char **) malloc((nlines + 1) * sizeof(char *));
q = p;
while(*p) {
if (*p++ == '\n') {
*(p-1) = 0;
*lstmp++ = q; /* Pointer to start of string */
q = p; /* Start next string */
}
}
*lstmp++ = p+1; /* Extra entry in linestarts for
main loop -- needed for comparison
for last character on line. */
return linestarts;
}
/*************************************
* Return number of lines in buffer.
**************************************/
int number_lines(p)
char *p;
{
int i = 0;
fprintf(stderr, "Counting lines...\n");
while(*p) {
if (*p++ == '\n') {
i++;
}
}
return i;
}
--------------------------- END INCLUDE --------------------
Here is a perl script to build text files (randline):
--------------------------- BEGIN INCLUDE --------------------
#! /usr/local/bin/perl
#--------------------------------------------------
# Generate text file with random data, lines being
# of random length, up to a certain length, and
# number of lines being specified.
#--------------------------------------------------
die "usage: randline numlines linelenth\n"
unless @ARGV == 2;
($numlines, $linelength) = @ARGV;
$short_pattern = "abcdefghijklmnopqrstuvwxyz";
$scale = int($linelength / length($short_pattern)) + 1;
$pattern = $short_pattern x $scale;
for($i=0; $i<$numlines; $i++) {
$offset = rand(length($short_pattern));
$length = rand($linelength);
$string = substr($pattern, $offset, $length);
print "$string\n";
}
--------------------------- END INCLUDE --------------------
Here is an abbreviated transcript of the comparison (on a Spar20):
--------------------------- BEGIN INCLUDE --------------------
### Build the test file (100 = length of longest line, numlines = 30000 ###
%./randline 100 30000 > text
### Transpose text file ###
%time ptranspose text > prot
User: 35.820 System: 1.310 Elapsed: 0:40.63 Percent CPU: 91.3%
%time transpose text > rot
User: 3.130 System: 0.290 Elapsed: 0:03.66 Percent CPU: 93.4%
### Untranspose the transposed text file ###
%time ptranspose prot > punrot
User: 29.960 System: 0.460 Elapsed: 0:32.84 Percent CPU: 92.6%
%time transpose rot > unrot
User: 3.450 System: 0.380 Elapsed: 0:03.99 Percent CPU: 95.9%
### This was with no C optimization, and with perl version 5.003.
--------------------------- END INCLUDE --------------------
--
Matthew Pressly
mattp@oakhill.sps.mot.com
------------------------------
Date: Mon, 17 Mar 1997 10:32:34 -0600
From: Alan Vu <axvu@netmail.mnet.uswest.com>
Subject: Re: Can 5.01 handle 4.0.1.8 scripts?
Message-Id: <332D7222.15D5@netmail.mnet.uswest.com>
Hi Marshall:
Try the following link:
http://perl.com/perl/all_about/perl425.html
Good luck
Marshall Pierce wrote:
>
> I thought 5.01 could correctly deal with 4.0 syntax? If this is not the
> case, is there a comprehensive list somewhere which identifies those
> things which would have to be changed. Even better, is there a conversion
> tool?
>
> Thanks
------------------------------
Date: 17 Mar 1997 12:00:33 -0700
From: Vladimir Alexiev <vladimir@cs.ualberta.ca>
Subject: Re: continuation-passing and tail-recursion
Message-Id: <omohci1gz2.fsf@tees.cs.ualberta.ca>
In article <5gj1qe$3fh@calf.saltfarm.bt.co.uk> aeb@calf.saltfarm.bt.co.uk (Tony Bass) writes:
> # The recursion can be put in tail position using
> # the usual device of an accumulating parameter,
> ......
> # but perl still uses stack space proportional to list length.
Not if you use the magical 'goto &foo' command, which replaces the current
call with a call to &foo. You can't pass args to &foo; the current value of @_
is used instead. And since in your case you'd be doing 'goto &sub4a' inside
&sub4a, it will look very much like iteration, using a label to the beginning
of the sub. Which is the most natural way anyway; perl being not lisp.
> # A technique perhaps better suited to machines than people
I'm sure some lispers will take offense here :-)
> # Instead of a value-returning subroutine we can use a subroutine applying
> # an added continuation parameter to what it calculates,
Continuations are widely used in functional programming ever since JR Steele's
famous MIT AI MEMO "Lambda, the ultimate imperative".
> # a common driver routine, so that the built-in stack nests just two
> # subroutines deep, no matter how long the list of numbers.
> for (;;) {
> ($f, @args) = &$f(@args);
> }
> # which is the last assignment and loop we will ever have to write.
And you wouldn't need even this if you had a fixpoint operator Y such that for
any &f, Y(&f)=&f(Y(&f)). Or other similar recursion device.
> # We also need built-in printing and stopping continuations,
You can dispense even with these wide-reaching side effects (IO) if you assume
that your STDIN and STDOUT are functional streams. A popular functional
language, Haskell, uses the technical device of "monads" to implement purely
functional IO.
> # would involve the lexical closure mechanism and so demand more of the
> # underlying language.
In fact lexical scoping is more natural and easy to implement than dynamic
scoping. I regard the fact that 'local' was before 'my' in perl as a historic
accident.
> # It now becomes clear that all the identifiers can be dispensed with,
> # and likewise the do and returns, that are now no more than visual markers,
NOW I understadn what you meant by "more suited to machines than to humans"!
> sub { $_[0], @_; }, sub {
> (! @{$_[1]}) ? ($_[2], 0, @_[3..$#_]) :
> $_[0], $_[0], [@{$_[1]}[1..$#{$_[1]}]], sub {
> $_[2], $_[1]+$_[0], @_[3..$#_];
> }, ${$_[1]}[0], $_[2], @_[3..$#_];
> }, [1, 2, 3], \&printit,
>
> # This is now just syntactic sugar for some Curry-Feys-Schoenfinkel
> # combinators.
You call THIS sugar? I'd say it's syntactic vinegar. One can at least read
lambda notation.
> # It is a pity that "sub" is still needed, but apart from that it is
> # all punctuation. Most satisfactory.
Great sense of humor! :-)
------------------------------
Date: Mon, 17 Mar 1997 17:14:57 +0100
From: Ling <ling@esbs.u-strasbg.fr>
Subject: getting IP address with gethostbyaddr ?
Message-Id: <332D6E01.446B@esbs.u-strasbg.fr>
Hi,
Does somebody show me an example of querying an IP name address knowing
the IP dotted address.
I tried th following, but something is wrong, maybe syntax or more ...?
$addr=pack('C4',130,79,76,22);
($name,$aliases,$addrtype,$length,@addrs)=gethostbyaddr($addr,AF_INET);
Thanks
--
____________
Claude LING
CNRS ESBS Boulevard Sebastien Brant, Pole API
67400 STRASBOURG-ILLKIRCH FRANCE
Tel : (0033) 03.88.65.52.72
Fax : (0033) 03.88.65.52.62
e_mail : Claude.Ling@esbs.u-strasbg.fr
------------------------------
Date: Mon, 17 Mar 1997 18:11:48 +0100
From: Fredrik Lindberg <flg@vhojd.skovde.se>
To: Ling <ling@esbs.u-strasbg.fr>
Subject: Re: getting IP address with gethostbyaddr ?
Message-Id: <332D7B54.867@vhojd.skovde.se>
Ling wrote:
>
> Does somebody show me an example of querying an IP name address knowing
> the IP dotted address.
Hi, use the Socket package!
#!/usr/bin/perl
use Socket;
$IPAdress = "194.16.15.19";
$DNSName = (gethostbyaddr(inet_aton($IPAdress), AF_INET))[0];
print "$DNSName\n";
__END__
You can find out more by doing a "perldoc Socket" !
hope this helps
/Fredrik
------------------------------
Date: Mon, 17 Mar 1997 17:17:08 -0800
From: Jan Krynicky <Jan.Krynicky@st.ms.mff.cuni.cz>
To: Your Name <username@teleport.com>
Subject: Re: How do I make the <STDIN> invisible?
Message-Id: <332DED14.1479@st.ms.mff.cuni.cz>
Your Name wrote:
>
> I want to have some sort of password thing, and I want the input to be invisble.
>
> For example,
>
> print 'Login: ';
> $login = <STDIN>;
> chop $login;
>
> print "\nPassword: ";
> $password = <STDIN>;
> chop $password;
>
> Is there something I use instead of <STDIN>? I don't want them to see the
> password, but I do want them to see the login.
>
> Also:
>
> How many different $ENVs are there when you get info from another computer?
>
> AJ Murray
> ajmurray@teleport.com
Try to put system "stty -echo"; before the reading and system "stty
echo";
####
print 'Login: ';
$login = <STDIN>;
chop $login;
print "\nPassword: ";
system "stty -echo";
$password = <STDIN>;
system "stty echo";
chop $password;
# ...
####
May work only under unix (tested under Solaris).
ad 2) Print them and you will see.
Jenda
------------------------------
Date: Mon, 17 Mar 1997 06:50:19 -0800
From: Odin <chuckr@ptw.com>
Subject: Re: learning perl
Message-Id: <332D5A2A.12E6@ptw.com>
Clay Irving wrote:
[ mailed and posted ]
In <3329EEC6.537B@pobox.com> sean <henriques@pobox.com> writes:
>any suggestions on how a newbie can painlessly pickup the basics of
>perl?? Perhaps an online tutorial ??
Try: Perl Reference/Tutorials, Guides, and FAQs
http://www.panix.com/~clay/perl/query.cgi?tutorials+index
>pls. respond to mailto://henriques@pobox.com
Is that a valid URL? :)
--
Clay Irving See the happy
moron,
clay@panix.com He doesn't give a
damn,
http://www.panix.com/~clay I wish I were a
moron,
My God! Perhaps I
am!
Yes, that is a valid URL. I just looked this morning in California.
Hey! That "CGI Made Real Easy" looks like something I can click on! Have
fun...
Chuck
------------------------------
Date: Mon, 17 Mar 1997 09:47:01 -0600
From: Alan Vu <axvu@netmail.mnet.uswest.com>
Subject: Re: matching whitespace?
Message-Id: <332D6775.2567@netmail.mnet.uswest.com>
alex filippenko wrote:
> i know i could look it up but i am 20min away from any perl book....sorry
> how do I match an intederminate amount of whitespace...
> i thought... /' '.*/... but doesn't work..
> Daniel
You are half way right. \s is used for whitespace character.
So you can use \s* for whitespaces
Hope It is useful.
------------------------------
Date: 17 Mar 1997 17:50:31 GMT
From: Tom Christiansen <tchrist@mox.perl.com>
Subject: Re: matching whitespace?
Message-Id: <5gk097$snj$1@csnews.cs.colorado.edu>
[courtesy cc of this posting sent to cited author via email]
In comp.lang.perl.misc, Alan Vu <axvu@netmail.mnet.uswest.com> writes:
:You are half way right. \s is used for whitespace character.
:So you can use \s* for whitespaces
Common mistake. You need \s+ for whitespaces. If you think
that asking whether something has whitespaces is done this way:
"NOBLANKS" =~ /\s*/
you'll be very very unhappy.
--tom
--
Tom Christiansen tchrist@jhereg.perl.com
You know, by the time you get done with all this, the "Swiss Army
Chainsaw" is going to be more like a Swiss Army Tactical Nuke.... :-)
--Brandon Allbery on perl in <1991Feb21.002412.20045@NCoast.ORG>
------------------------------
Date: Mon, 17 Mar 1997 16:09:17 GMT
From: gerlach@netcom.com (Matthew H. Gerlach)
Subject: Re: Pattern matching on stream
Message-Id: <gerlachE773JH.3uA@netcom.com>
Comm.pl is pretty much functionally equivilent to expect, but you
won't need to learn TCL.
In article <JFRIEDL.97Mar15053759@tubby.nff.ncl.omron.co.jp> jfriedl@ora.com writes:
>
>On 12 Mar 1997 18:09:30 GMT, Peter Scott wrote:
>> This sounds a bit odd but it would be useful. I am wondering if
>> there is such a thing as a streaming pattern match, which is the
>> best term I can come up with.
>
>There's a great way to do it in perl:
> system("expect")
>:-)
>
>[Expect is a tool that does, among other things, continual matching on an
> input stream]
>
> Jeffrey
>----------------------------------------------------------------------------
>Jeffrey Friedl <jfriedl@ora.com> Omron Corp, Nagaokakyo, Kyoto 617 Japan
>See my Jap<->Eng dictionary at http://www.wg.omron.co.jp/cgi-bin/j-e
>O'Reilly's Regular Expression book: http://enterprise.ic.gc.ca/~jfriedl/regex/
>
------------------------------
Date: 17 Mar 1997 11:24:24 -0500
From: Tom Fawcett <fawcett@nynexst.com>
Subject: Re: Pattern matching on stream
Message-Id: <8jsp1uo5af.fsf@nynexst.com>
pjscott-remove-to-email@euclid.jpl.nasa.gov (Peter Scott) writes:
> This sounds a bit odd but it would be useful. I am wondering if
> there is such a thing as a streaming pattern match, which is the
> best term I can come up with. Let me illustrate. A common task
> is to scan a file until some pattern is found and set a variable,
> so the code is something like:
>
> while (<INPUT>) {
> $found = 1, last if /foo/;
> }
>
> Now suppose pattern foo might match across multiple lines (so we'll
> have some \s in foo and a /s qualifier). Can't do the above; if you
> know how many lines it might match across you can push each new line
> onto an array, shift off the first one to go out of bounds, and match.
> Ugly, and what about when you don't know how many lines it might match
> across? You can slurp the whole file into a string (and I usually do),
> but this is wasteful, especially if you're searching potentially long
> files for strings which are probably near the beginning (the example
> which prompted this is searching for <META> tags in HTML).
>
> It doesn't seem unreasonable to want to say, "Read as much of the
> file as you need to either match this or reach EOF," although it
> doesn't sound like an easy thing to implement, and I haven't found
> anything like it on CPAN. Anyone got any brilliant suggestions for
> doing it?
An interesting problem. An obvious way of doing it is something like:
$str = "";
while (<INPUT>) {
$str .= $_;
if ($str =~ /pattern/) { $found = 1; last; }
}
But this re-invokes the pattern match on every new line, which may be far
too expensive if the pattern is complex. Also it doesn't shift text off
the end of $str if it knows it can't match, so if the match is toward the
end of the file you waste space and time.
I think the answer is that you need more information about partial matches
and failures than Perl's RE mechanism provides. The first idea (matching
on a moving window of text) sounds like a good compromise, if you can bound
the window size.
-Tom
------------------------------
Date: Mon, 17 Mar 1997 09:08:10 -0800
From: Rick Tan <rick.tan@Eng.Sun.COM>
Subject: perl -w
Message-Id: <332D7A7A.33E7@Eng.Sun.COM>
Hi,
What does the following message telling me?
Use of uninitialized value at ./craid.GOOD line 432, <INPUT> chunk 1.
In my Perl script, I have the following:
open (INPUT, "somefile");
.
.
.
while (chop($line=<INPUT>) { ===> line 432
Thanks.
------------------------------
Date: Mon, 17 Mar 1997 11:15:37 -0500
From: Bob_Franklin@illinova.com
Subject: perl and cgi
Message-Id: <332D6E29.E33@illinova.com>
Is there a Perl plug-in or is there a way to preload Perl
for the Netscape and Oracle Web Servers (Unix/NT)?
I want to avoid the overhead of loading the Perl executable
each time a Perl CGI script is invoked.
(I know MS IIS has perliis.dll.)
------------------------------
Date: Mon, 17 Mar 1997 19:08:57 GMT
From: steve@golf.com (Steven Sajous)
Subject: Perl Compiler
Message-Id: <332d9693.3914652@news1.alterdial.uu.net>
Does anyone know where I can find a Perl compiler, and have any
instr5uctions on how to use one?
------------------------------
Date: 17 Mar 1997 16:27:36 GMT
From: "Jonathan Tracey" <jont@uunet.pipex.com>
Subject: Perl for NT ***Help****
Message-Id: <01bc32f0$42c26ff0$0600000a@salmon>
Please help me before I go insane!
How can I stop the Perl window closing as soon as it encounters an error. I
cannot read the error messages as the windows closes like lightning.
Any help would be appreciated.
Thanks
Jon Tracey
------------------------------
Date: 17 Mar 1997 10:38:21 -0800
From: Russ Allbery <rra@cs.stanford.edu>
To: "Harry Kas" <harry@bci.se>
Subject: Re: Q: How can I read the full pathname
Message-Id: <qumu3mabbz6.fsf@cyclone.stanford.edu>
[ Posted and mailed. ]
Harry Kas <harry@bci.se> writes:
> I should like to get a list of all the files in my directory and in all
> its subdirectories, with full pathname. Does somebody knows a good
> method, using 'Readdir'? I should get as result the full pathname,
> e.g. /usr/test, /usr/test2, /usr/user2/test.
This will do a single directory. To handle the recursion on multiple
directories, you can either test each file in the directory with -d and
recurse yourself if it's a directory, or you can use File::Find.
#!/usr/bin/perl -w
use Cwd;
my $directory = shift or die "$0: no directory specified\n";
# Get full canonical name of directory. It's easiest to just let the file
# system and OS do this for us than to try to figure it out for ourselves.
chdir $directory;
$directory = cwd;
# Grab the list of files and prepend the canonical directory name to them.
opendir (DIR, '.') or die "$0: cannot open directory $directory: $!\n";
@files = readdir DIR;
closedir DIR;
for (@files) { $_ = $directory . '/' . $_ }
# Now @files contains the fully qualified list of files. We would
# normally go on to do something else with them (and would probably want
# to chdir back to our original directory), but since this is just a demo,
# we'll just print them out.
print join ("\n", @files), "\n";
--
Russ Allbery (rra@cs.stanford.edu) <URL:http://www.eyrie.org/~eagle/>
------------------------------
Date: 17 Mar 1997 08:57:17 -0800
From: klewall@uvaix3e1.comp.UVic.CA (Kim Lewall)
Subject: Signaling a child process
Message-Id: <5gjt5d$1req@uvaix3e1.comp.UVic.CA>
I have a process which forks off a child. In the
following simple example, the parent and child both
start and then effectively wait.
If I kill -s HUP the parent, the quit routine is
invoked, and the response from kill('TERM', $pid);
is 1, but the child never dies??? If I kill -s HUP the
child, it never seems to get it.
So why does it appear that the child never gets signals?
This is perl, version 5.003 with EMBED
built under aix 4.1.4
-------------------------------
#!/usr/local/bin/perl -w
sub quit {
local($Sig) = @_;
return if $pid == 0;
if ($Sig) { print STDERR "Caught a SIG$Sig -- killing $pid\n" }
kill('TERM', $pid);
waitpid($pid, 0);
exit(0);
}
$SIG{'HUP'} = $SIG{'INT'} = $SIG{'QUIT'} = $SIG{'TERM'} = \&quit;
if ($pid = fork) {
print "parent waiting 1 $pid\n";
waitpid($pid, 0); #parent
print "parent waiting 2 $pid\n";
} elsif (defined $pid) { #child
print "child running 1 $pid\n";
$SIG{'HUP'} = $SIG{'INT'} = $SIG{'QUIT'} = $SIG{'TERM'} = \&quit;
while (1) {
sleep(1);
print "child sleeping\n";
}
print "child running 2 $scriptpid\n";
}
exit(0);
------------------------------
Date: Mon, 17 Mar 1997 17:59:03 +0000
From: Douglas Seay <seay@absyss.fr>
Subject: Re: sourcing (bash) config files within perl
Message-Id: <332D8667.1AF1@absyss.fr>
Laurence Molloy wrote:
>
> Hi,
>
> Does anybody have an answer to this problem that doesn't involve
> actually reading in the necessary config files and assigning each
> variable manually by pattern matching, or including the variables in the
> .bashrc file?...
Laurence,
I'm not replying to you in particular, but to all the
people who talk about this sort of thing. You are not
the first who has wanted to read a shell file.
First of all, with the Unix process model, it won't
be possible spawn a sub-process and have it change
the environment of the parent (Perl) process.
Secondly, how often do you try to "source" fortran
files in C? How often do you get your Perl scripts
to "source" C?
For both cases, there are solutions (.o files and XS)
but neither one is automatic nor completely painless.
Life would be easier if you made sure that the environment
was already loaded when you Perl script was launched.
Other than that, you'll need something that can understand
bash syntax (don't forget HERE documents and comments)
to look for assignments. You'll need to keep track of
if/else blocks too. Don't forget shell procedures.
Sorry, but language translation isn't trivial.
Below is something that I wrote for someone who created
a file of variables
X1=Y1
X2=Y2
etc
and wanted them loaded in any shell. This little
program uses awk (ugh) for portability reasons, but
it isn't too hard to read. It supports sh/csh/ksh
style exported variables. You can easily throw
in an extra case for perl which will do
$ENV{something} = $somethingelse;
after that just try
my $tmpfile = `this_stupid_awk_thing $file perl`;
chomp($tmpfile);
require $tmpfile;
unlink $tmpfile;
or something kinda close.
Of course, maybe it is too hard for you to rewrite
you bash script in this syntax. In that case, I'd
say to think long and hard about the problem and see
if there isn't another approach.
good luck
doug seay
PS - "comp.lang.perl" is old and should not be used.
"comp.lang.perl.misc" is the real name.
---------{ SOURCE }---------
#!/bin/sh
program=`basename $0`
file=$1
format=$2
tmpfile=$3
awk=`type gawk nawk awk 2>&1 | grep -v " not " | sed -n 's/.* is
\//\//p' | head
-1`
if [ -z "$awk" ] ; then
echo "could not find an awk program"
exit 1
fi
# echo "# program $program" 1>&2
# echo "# file $file" 1>&2
# echo "# format $format" 1>&2
# echo "# tmpfile $tmpfile" 1>&2
if [ -z "$file" -o -z "$format" ] ; then
echo "error: too few parameters"
echo " "
echo "usage: $program source_file format [tmpfile]"
echo " "
echo " source_file is the name of a file with 'name=value'"
echo " pairs, one per line"
echo " format must be one of the following"
echo " 'sh' for bourne shell 'name=value ; export
name'"
echo " 'csh' for c shell 'setenv name value'"
echo " 'export' for korn shell 'export name=value'"
echo " tmpfile [if supplied] is the name of the file to write"
echo " the output. if not supplied, one will be
generated"
echo " using the process id number."
echo " "
echo "the name of the file (either supplied or generated) will"
echo "be returned on stdout. it is the job of the caller to"
echo "delete this file when done."
exit 1
fi
if [ -z "$tmpfile" ] ; then
tmpfile="/tmp/$program.$USER.$$"
fi
$awk -v FORMAT=$format 'BEGIN { printf("# format --%s--\n", FORMAT); }\
{ \
equal=index($0, "=");
var=substr($0,1,equal-1);
val = sprintf("\"%s\"", substr($0,equal+1) );
if ( length(var)=="0" || var !~ /^[a-zA-Z0-9_]+$/ )
printf("# illegal variable name \"%s\"\n", var);
else if ( FORMAT=="sh" ) printf("%s=%s ; export %s\n", var, val,
var);
else if ( FORMAT=="csh" ) printf("setenv %s %s\n", var, val);
else if ( FORMAT=="export" ) printf("export %s=%s\n", var, val);
else { printf("# unknown format %s\n", FORMAT); exit 1; };
}' < $file > $tmpfile
echo $tmpfile
------------------------------
Date: Mon, 17 Mar 1997 18:00:51 +0100
From: Fredrik Lindberg <flg@vhojd.skovde.se>
To: frax@goliat.publ.ica.se
Subject: Re: Splitting a multi line string
Message-Id: <332D78C3.5A67@vhojd.skovde.se>
Fredrik Axtelius wrote:
>
> I got a multi line string that I need to
> split in 2 pieces at the first word that ends with :
How about split() ?
#!/usr/bin/perl
#
$string = <<END;
sad
asdas
someword:
newword
asas
asdasd
someotherword:
asas
asas
END
@Strings = split(/:\s*\n/,$string);
foreach $str (@Strings) {
print "\nString is \"$str\"\n";
}
__END__
You can find out more about split in the perlfunc man page.
Hope this helps
/Fredrik
------------------------------
Date: 17 Mar 1997 11:33:29 -0700
From: Vladimir Alexiev <vladimir@cs.ualberta.ca>
Subject: Re: What language do Perl REs recognize?
Message-Id: <ompvwy1i86.fsf_-_@tees.cs.ualberta.ca>
In article <332D2587.5F06@absyss.fr> Douglas Seay <seay@absyss.fr> writes:
> > /([abc]*)\1/
> > You get a language that I can't see how to describe with a CFG.
Right, this is one of the simplest examples of a CSG. Funny enough,
palindromes (strings whose reverse is the same as the original) *are* CFG. Eg
S -> aSa|bSb|cSc (a CFG); and I don't see how this can be described in perl.
> > there wasn't any plateau above context free
Wrong, there are context-sensitive languages.
> IIRC, the Chomsky Hierarchy has the following levels
And I'm adding the corresponding recognizers (AFAI can remember):
> Regular Languages FSM, finite state
> Context Free Languages (BNF) PDA, stack machines
> Context Sensitive Languages linear-space turing machines
> Phrase-structure languages Turing Machines
> All Possible Languages can't be described in any finite formalism
because there's |R| langs, but only |N|
descriptions
> The backreference is not regular, and I don't think that it is CF either. If
> so, this little oddball breaks the standard hierarchy.
Seems to me it is context-sensitive.
------------------------------
Date: 8 Mar 97 21:33:47 GMT (Last modified)
From: Perl-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Digest Administrivia (Last modified: 8 Mar 97)
Message-Id: <null>
Administrivia:
The Perl-Users Digest is a retransmission of the USENET newsgroup
comp.lang.perl.misc. For subscription or unsubscription requests, send
the single line:
subscribe perl-users
or:
unsubscribe perl-users
to almanac@ruby.oce.orst.edu.
To submit articles to comp.lang.perl.misc (and this Digest), send your
article to perl-users@ruby.oce.orst.edu.
To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.
To request back copies (available for a week or so), send your request
to almanac@ruby.oce.orst.edu with the command "send perl-users x.y",
where x is the volume number and y is the issue number.
The Meta-FAQ, an article containing information about the FAQ, is
available by requesting "send perl-users meta-faq". The real FAQ, as it
appeared last in the newsgroup, can be retrieved with the request "send
perl-users FAQ". Due to their sizes, neither the Meta-FAQ nor the FAQ
are included in the digest.
The "mini-FAQ", which is an updated version of the Meta-FAQ, is
available by requesting "send perl-users mini-faq". It appears twice
weekly in the group, but is not distributed in the digest.
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 V8 Issue 132
*************************************