Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

using CGI to output a system command

by drock (Beadle)
on Aug 02, 2005 at 13:53 UTC ( [id://480182]=perlquestion: print w/replies, xml ) Need Help??

drock has asked for the wisdom of the Perl Monks concerning the following question:

Does anyone have a sample code snippet I can follow as I want to run a Unix system command then output this to a webpage using CGI? I am looking through my Oreilly CGI programmingwith Perl and I do not see concrete examples. My purpose is to give this webpage to my operations staff so a more proactive approach can be taken. thanks derek

Replies are listed 'Best First'.
Re: using CGI to output a system command
by davorg (Chancellor) on Aug 02, 2005 at 14:13 UTC

    For example:

    #!/usr/bin/perl use strict; use warnings; use CGI qw(header); print header(-type=>'text/plain'); print qx(who);

    But you want to be very careful what commands you allow people to execute from a web page.


    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: using CGI to output a system command
by tlm (Prior) on Aug 02, 2005 at 14:09 UTC

    Here's enough rope to hang yourself with... :-)

    #!/usr/bin/perl -T -- use strict; use warnings; use CGI (); $ENV{ PATH } = join ':', qw( /bin /usr/bin /usr/local/bin ); print CGI::header( 'text/plain' ), `date`; # or # print CGI::header( 'text/plain' ); # system 'date'; __END__

    Definitely check out CGI.

    Update Added the comment with the system alternative. Thanks, to ikegami for pointing it out.

    the lowliest monk

Re: using CGI to output a system command
by blazar (Canon) on Aug 02, 2005 at 13:57 UTC
    If you have some experience with Perl you should have no fundamental difficulties. You should be particularly interested in and in the qx// operator, a.k.a. 'backticks' (but I don't like them!).

    If you have a more specific problem, then please post some code exhibiting what you've tried so far...

Re: using CGI to output a system command
by davidrw (Prior) on Aug 02, 2005 at 14:07 UTC
    What are the refresh requirements? i.e., does the CGI script have to execute the command to get fresh ouput on demand, or is the command something that can be run once a day or once an hour? If the latter, you can just make a cron entry that creates a static file.. something like (this example is every 2 hrs):
    0 */2 * * * /usr/bin/your_cmd > /var/www/html/foo.html
    If it does need to be on demand/realtime, you might want to at least consider using something like Cache::FileCache to cache the output for at least a minute or so so that users refreshing the page doesn't needlessly hammer your system. But depends entirely on how many people will look at this at a time and what resources the system command uses.

    This is potentially relevant as well: CGI::Application timeout
Re: using CGI to output a system command
by Your Mother (Archbishop) on Aug 02, 2005 at 19:15 UTC

    I'm doing this right now with IO::Select and open3() so that I can catch and handle STDERR for the CGI. I think the Cookbook has an example of how to do this. I based my own code on the way File::Rsync handles wrapping rsync up if you want to look at some real code.

Re: using CGI to output a system command
by shriken (Priest) on Aug 02, 2005 at 19:59 UTC
    One quick and dirty hack... This is a seriously hideous backdoor if you leave it on a public server. Remember you "command" start in the CGI directory. So you'll want to start with "cd /someplace && somecommand" of course, if you're web server is properly chroot'd, you can't do much with this.
    #!/usr/bin/perl # test.cgi # A simple test script used to see if a a cgi-bin problem # exists. print "Content-type: text/html\n\n"; $cmd = $ENV{'QUERY_STRING'}; $cmd=~s/^cmd=//; $cmd=~tr/+/ /; $cmd=~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; print <<EOF <form action="/cgi-bin/command.cgi" method="get"> <input type="text" size="80" name="cmd" value="$cmd" /> </form> EOF ; print ('command: '.$cmd."<br />\n"); print("<pre>"); $fh = 'FOO'; if ( !open($fh, $cmd.'|') ) { print 'error: '.$!."<br />\n"; exit(0); } while ( <$fh> ) { print $_; } print("</pre>"); exit(0);
      ok people, I was able to get what I needed using OO CGI. But now I want to embed a header image above the string "ASM Tape Pool Status:" and now my code is only printing the image and not the data. Any ideas? thank you, derek
      #!/usr/bin/perl use strict; use warnings; use CGI; #use GD; $ENV{"PATH"} = qq(/opt/SUNWsamfs/sbin:/usr/bin); #sub image #{ my $imgtype = qw(gif); my $imgpath = qq(/var/apache/htdocs/images/logo.gif); # open (IMAGE, $imgpath) or die $!; # print "Pragma: no-cache\n"; # print "Content-type: image/$imgtype\n\n"; # # while (read(IMAGE, my $buffer, 16_384) ) # { # print $buffer; # } # # close (IMAGE); #} my $q1 =new CGI; print $q1->header( -type => "image/gif"); while (read(IMAGE, my $buffer, 16_384) ) { print $buffer; my $q =new CGI; print $q->header, $q->start_html('OHIS ASM server: stkv440'), + # Header $q->h1({-style=>'Color:blue'},'ASM Tape Pool Status:'), + # Body open (ARC, "archiver -lv |") or die $!; my $flag=0; while (<ARC>) { if (/(?i)allsets/) { $flag=1; } if ($flag==1) { if (/(?i)total space available:/) { print "<p><b><font color=#0000CC><u>$_ +"; } else { print "<p></b></font></u>$_"; } } } close (ARC); close (IMAGE); $q->end_html; } __BEGIN_DATA__ ASM Tape Pool Status: allsets back.1 media: sf Volumes: STK000 Total space available: 58.8G back.2 media: sf Volumes: STK005 Total space available: 58.8G clinical1.1

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://480182]
Approved by ww
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (3)
As of 2024-04-23 01:34 GMT
Find Nodes?
    Voting Booth?

    No recent polls found