Apr 29 2007

前几日搞perl的笔记

Category: 技术ssmax @ 14:36:54

前几天搞一个空间的时候,php被禁止了system命令,只有用perl cgi来做了,研究了一下perl调用命令行,弄了一个web版模拟shell。

先贴资料:

How can I capture STDERR from an external command?

There are three basic ways of running external commands:

    system $cmd;
     $output = `$cmd`;
     open (PIPE, "cmd |");

In the first case, both STDOUT and STDERR will go the same place as the script’s versions of these, unless redirected. You can always put them where you want them and then read them back when the system returns. In the second and third cases, you are reading the STDOUT only of your command. If you would like to have merged STDOUT and STDERR, you can use shell file-descriptor redirection to dup STDERR to STDOUT:

    $output = `$cmd 2>&1`;
     open (PIPE, "cmd 2>&1 |");

Another possibility is to run STDERR into a file and read the file later, as in

    $output = `$cmd 2>&some_file`;
     open (PIPE, "cmd 2>&some_file |");

Note that you cannot simply open STDERR to be a dup of STDOUT in your perl program and avoid calling the shell to do the redirection. This doesn’t work:

    open(STDERR, ">&STDOUT");
     $alloutput = `cmd args`;
  # stderr still escapes

Here’s a way to read from both of them and know which descriptor you got each line from. The trick is to pipe only STDOUT through sed, which then marks each of its lines, and then sends that back into a merged STDOUT/STDERR stream, from which your Perl program then reads a line at a time:

    open (CMD, "(cmd args | sed 's/^/STDOUT:/') 2>&1 |");
    while () {
       if (s/^STDOUT://)  {
           print "line from stdout: ", $_;
       } else {
           print "line from stderr: ", $_;
       }
     }

Be apprised that you must use Bourne shell redirection syntax in backticks, not csh! For details on how lucky you are that perl’s system() and backtick and pipe opens all use Bourne shell, fetch the file from convex.com called /pub/csh.whynot — and you’ll be glad that perl’s shell interface is the Bourne shell.

There’s an &open3 routine out there which was merged with &open2 in perl5 production.

再贴偶的模拟shell,随便写了个。。

cmd.pl

#!/usr/bin/perl
use CGI;
my $command = CGI::param(‘command’);
my $pwd = CGI::param(‘pwd’) || ‘.’;

print (“Content-Type: text/plain;\n\n”);
print “change dir: “.`cd $pwd 2>&1`.”\n”;
print “now dir: “.`pwd`.”\n”;
print “command: “.$command.”\n\n”;
print `$command 2>&1`;

cmd.html

<html>
<body>
 <form name=”cmdform” action=”cgi-bin/cmd.pl” target=”cmdframe”>
 <div>
  work dir:
  <input type=”text” value=”.” name=”pwd” />
 </div>
 <div>
  input your command here:
  <textarea name=”command” cols=”100″ rows=”5″></textarea>
 </div>
 <Input type=”submit” value=”run”/>
 </form>
 
 <iframe name=”cmdframe” height=”100%” width=”100%”></iframe>
</body>
</html>

如果遇到 500 错误,最有可能是没有设置cmd.pl为可执行(755一般是),这个在后台log应该能看到,还有可能是遇到apache的Premature end of script headers错误,一般就是没有

print (“Content-Type: text/plain;\n\n”);

这句造成的,还有可能是dos换行符号造成,把cmd.pl里面所有\r\n换成unix的\n格式就好了。。。


Apr 29 2007

我胡汉三回来啦

Category: 乱up当秘笈ssmax @ 14:21:44

我胡汉三回来啦,哈哈,域名不知道死了多久。。。都忘记了

comx回来了,嗅嗅回来了,我现在的昵称是 回头是岸,富甲西游里面能研究的是回头卡。。。。

想起一首回头有关的诗:

      华工女生不回头,长发飘飘梦中游。
  广外女生不回头,看着背影就想搂。
  华工女生一回头,宿舍男生齐跳楼。
  广外女生一回头,倾倒整个男生楼。
  华工女生二回头,不爱美女爱猿猴。
  广外女生二回头,路上汽车乱碰头。
  华工女生三回头,吓死田中两头牛。
  广外女生三回头,天上牛郎返地球。
  华工女生四回头,庐山瀑布水倒流。
  广外女生四回头,世界小姐没人瞅。
  华工女生五回头,乔丹飞到外星球。
  广外女生五回头,嫦娥贵妃齐跳楼。
  华工女生六回头,哈雷彗星撞地球。
  广外女生六回头,白宫实习来招收。
  华工女生七回头,收复台湾不用愁。
  广外女生七回头,来年生源不用愁。
  华工女生八回头,武松醉倒三碗酒。
  广外女生八回头,太监都要抖一抖。
  华工女生九回头,马拉多纳打篮球。
  广外女生九回头,大款开车都领走。
  华工女生十回头,人类发展到尽头!
  广外女生十回头,泰坦尼克继续游!