简体   繁体   中英

Can I run a Perl script from stdin?

Suppose I have a Perl script, namely mytest.pl. Can I run it by something like cat mytest.pl | perl -e cat mytest.pl | perl -e ?

The reason I want to do this is that I have a encrypted perl script and I can decrypt it in my c program and I want to run it in my c program. I don't want to write the decrypted script back to harddisk due to secruity concerns, so I need to run this perl script on-the-fly, all in memory.

This question has nothing to do with the cat command, I just want to know how to feed perl script to stdin, and let perl interpreter to run it.

perl < mytest.pl 

should do the trick in any shell. It invokes perl and feeds the script in via the shell redirection operator < .

As pointed out, though, it seems a little unnecessary. Why not start the script with

#!/usr/bin/perl

or perhaps

#!/usr/bin/env perl

? (modified to reflect your Perl and/or env path)

Note the Useless Use of Cat Award . Whenever I use cat I stop and think whether the shell can provide this functionality for me instead.

Sometimes one needs to execute a perl script and pass it an argument. The STDIN construction perl input_file.txt < script.pl won't work. Using the tip from How to assign a heredoc value to a variable in Bash we overcome this by using a "here-script":

#!/bin/bash
read -r -d '' SCRIPT <<'EOS'
$total = 0;

while (<>) {
    chomp;
    @line = split "\t";
    $total++;
}

print "Total: $total\n"; 
EOS

perl -e "$SCRIPT" input_file.txt
perl mytest.pl 

should be the correct way. Why are you doing the unnecessary?

cat mytest.pl | perl

…is all you need. The -e switch expects the script as a command line argument.

perl will read the program from STDIN if you don't give it any arguments.

So you could theoretically read an encrypted file, decrypt it, and run it, without saving the file anywhere.


Here is a sample program:

#! /usr/bin/perl
use strict;
use warnings;
use 5.10.1;

use Crypt::CBC;

my $encrypted = do {
  open my $encrypted_file, '<', 'perl_program.encrypted';
  local $/ = undef;
  <$encrypted_file>;
};

my $key = pack("H16", "0123456789ABCDEF");
my $cipher = Crypt::CBC->new(
  '-key'    => $key,
  '-cipher' => 'Blowfish'
);
my $plaintext = $cipher->decrypt($encrypted);

use IPC::Run qw'run';
run [$^X], \$plaintext;

To test this program, I first ran this:

perl -MCrypt::CBC -e'
  my $a = qq[print "Hello World\n"];
  my $key = pack("H16", "0123456789ABCDEF");
  my $cipher = Crypt::CBC->new(-key=>$key,-cipher=>"Blowfish");
  my $encrypted = $cipher->encrypt($a);
  print $encrypted;
' > perl_program.encrypted

This still won't stop dedicated hackers, but it will prevent most users from looking at the unencrypted program.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM