Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Executing Unix command within Perl

Status
Not open for further replies.

santanudas

Technical User
Mar 18, 2002
121
0
0
GB
Hi guys,

I was trying to execute some Unix commands from within perl but getting error; especially when the command itself got a single quote in it. Say e.g. if I want to pipe through sed like this:
Code:
my $DIR = `pwd -PL | sed '\,^, s/.*\///'`;
I tried with backslash but didn't work. Any idea how to make it work? Any sort of help is very much appreciated. Thanks in advance.
 
try:

my $DIR = `pwd -PL | sed '\\,^, s/.*\\///'`;

This doesn't seem very perl-ey though.
 
Hi chazoid,

Thanks for your replay and it did work pretty well. But now I see another problem; a adding a white space is automatically being added at the end to the output. This is a sample script:
Code:
!/usr/bin/perl -W

use strict;
$ENV{"PATH"} = "/bin:/usr/bin";
my $DIR = `pwd -PL | sed '\\,^, s/.*\\///'`;
print "$DIR\_bb \n";
I’ve intentionally added that “_bb” to the print command so that I can see whether there is any thing else between $DIR value and “_bb”. Now if I run the script it outputs, 2 lines – the value of $DIR and _bb in two different lines, instead of one. Any idea what I’m missing?
 
$DIR has a newline on the end. Use chomp() to remove it.

Code:
my $DIR = `pwd -PL | sed '\\,^, s/.*\\///'`;
chomp($DIR);
print "$DIR\_bb \n";

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Ohhh yes, chomp(); I see I keep forgetting whatever the Perl I knew. Thanks travs69 and Kevin for your reply.

Any way, I have just another question: How can I use “strict” and global variable at the same time? In my script, I call every single sub-routine from a .cgi file and there are some variables common to every single script. So, I put those common variables in a .cgi file and my sub-routines are in .pl files. But If I do “use strict;” I see the common variables are not globally usable anymore. What’s the work around? Thanks again for your help.


 
There should be as few global variables as possible. You need to pass arguments to your subroutines/functions in the system array and return them back using return(). But all you have to do is define globals at the beginning of a script:

use strict;
my $foo = 'foo';
my $bar = 'bar';



------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
I'd also like to point out that using "my" at the beginning of the script still makes "local" variables, but in this case, the scope of the variables is the script itself... however, if you `require` other Perl scripts, these variables aren't available.

So you use "our" to make truly global variables that have no scope:

use strict;
our $foo = 'foo';
our $bar = 'bar';

-------------
Cuvou.com | My personal homepage
Project Fearless | My web blog
 
Hi there,

Thanks for the replies. I’m almost sure that “my” not gonna work, at least it’s not working me here. I do feel the “our” is the way to go with but that’s not working either here and I’m pretty sure, the reason is I’m not writing the code correct way. Here I’m going to provide a little bit of details of my scripting, hoping that will help you guys to understand what’s wrong.

Say, I got 4 scripts – getdata.pl, page1.pl, page2.pl and test.cgi; getdata.pl reads the html form data and make it available to test.cgi and my goal is to use one variable (e.g. $dir) in page1.pl and the make use of the value of that variable in the next page, which is page2.pl and so on.
Code:
sub getformdata {

use base 'Exporter';
$meth="";
$buffer="";
#our @EXPORT_OK = qw($FORM);
use vars qw($FORM);
#our $FORM;

$ENV{"PATH"} = "/bin:/usr/bin";
$meth=$ENV{'REQUEST_METHOD'};

if($meth eq "POST") {
  read(STDIN, $buffer1, $ENV{'CONTENT_LENGTH'});
  $buffer2=$ENV{'QUERY_STRING'};
  $buffer=$buffer1 . '&' . $buffer2;
} elsif ($meth eq "GET") {
  $buffer=$ENV{'QUERY_STRING'};
}

@p=split(/&/, $buffer);
foreach $p (@p) {
   ($nm,$vl) = split(/=/, $p);
   $vl =~ tr/+/ /;
   $vl =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
   $vl =~ s/~!/ ~!/g;
      #if (not exists($FORM{$nm})){
      if($FORM{$nm} ne '') {
       $FORM{$nm} = $FORM{$nm} . ',' . $vl;
      } else {
       $FORM{$nm} = $vl;
      }
  }
}
1;
the page1.pl is something like this:
Code:
sub page1 {

use strict;

$ENV{"PATH"} = "/bin:/usr/bin";
my ($dir, $com_path);

chomp( $dir = `pwd -PL | sed sg.\*/ggg` );     # present working directory
$com_path = $dir . "/common";		       # data directory

# and then I pass the varaibale to test.cgi like this:  
print <<HTML1;
<form name="idxform"  action="test.cgi" method="post">
...
...
<a href=\"/cgi-bin/project/$test.cgi?MODE=PAGE2&DIR=$dir"\>Go to next page</a>
....
....
</form>
HTML1
1;

now a sample page2.pl should be like this, I mean according to my scripting:
Code:
sub page2 {

use strict;
my sys_dir = "/path/to/the/project/$p_dir" 
# NOTE :: $p_dir suppose to be global and defined in test.cgi
# and then the html form like page1.pl
print <<HTML1;
....
....
....
HTML
1;
and this the test.cgi
Code:
#!/usr/bin/perl -swU

require "getdata.pl";		#getformdata()
require "page1.pl";		#indexView()
require "page2.pl"; 		#thumbView()

#use strict;
use integer;
use base 'Exporter';
use URI::Escape;

use vars qw($p_dir $FORM);
our( $query, $FORM );

$query = $ENV{QUERY_STRING};
my @pairs = split(/\&/, $query);
foreach my $pair (@pairs) {
   my ($var,$value) = split(/=/, $pair, 2);
   $value = uri_unescape ($value);
   $FORM{$var} = $value;
}

&getformdata();

my $mode = $FORM{MODE};
our $p_dir = $FORM{DIR};
our $imgs = $FORM{IMGS};

if( $mode eq "" ) {
  $mode = "MAIN";
}

sub MAIN {
  &page1();
}

sub PAGE2 {
  &page2();
}
# and like this one by one as required

Now this works perfectly well as it is now, i.e. “use strict;” commented out in the test.cgi but as soon as I enable it, I get these type of errors:

[error] Variable "%FORM" is not imported at test.cgi
[error] Global symbol "%FORM" requires explicit package name at test.cgi
[error] Execution of test.cgi aborted due to compilation errors.
[error] Premature end of script headers: test.cgi


That's the way I always do Perl/CGI and this is the problem I having at the moment. I also want to enable "strict" in the getsdata.pl but can't figure out how make it happen. So, any idea what’s wrong I’m doing here? I do really very much appreciate you cooperation.

Sorry for this very long post but I thought this is the best way to make you guys understand my problems. Many thanks.

 

It can't be possible that no one knows how to do that. Any one
out here can help?? please?? Cheers!!!

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top