如何使用php网页上的expect脚本?

时间:2009-06-22 11:15:49

标签: php linux exec rsync expect

当我尝试从我的debian上的php5执行程序时,网页冻结并且程序什么都不做。 当我从命令行调用它时,此脚本有效。安全模式已禁用。 Echo stdout不起作用(因为冻结)。 我在google中读到了一些有关www权限的答案,但如果有人在这里有快速简单的回复......

如何调试?

php调用

exec("expect scripts/sshtest.exp $module");

脚本代码(我在这里找到http://bash.cyberciti.biz/security/expect-ssh-login-script/

#!/usr/bin/expect -f
# set Variables
set module [lrange $argv 0 0]
set timeout -1
# rsync 
spawn rsync -aCb --progress --delete --backup-dir=/var/www/blabla.com/rsyncBackups/BackupedFilesFromServer23_on_  /var/www/blabla/$module  -e ssh root@10.10.10.10:/root/$module
match_max 1000000
# Look for passwod prompt
expect "*?assword:*"
# Send password 
send -- "THEPASSWORD\r"
# send blank line (\r) to make sure we get back to gui
send -- "\r"
expect eof

8 个答案:

答案 0 :(得分:1)

尝试

passthru("expect scripts/sshtest.exp $module 2>&1");

2>&1stderr重定向到stdout并使用passthru代替exec将为您提供所有输出。

答案 1 :(得分:1)

为什么要使用期望? 设置rsync以使用公钥/私钥(请参阅http://troy.jdmz.net/rsync/index.html),您不必使用expect来输入密码。

答案 2 :(得分:1)

我有同样的问题,这让我疯了。我参加派对的时间有点晚了,但我想我会发布一个解决了我的问题的解决方案,万一其他人遇到这个帖子并遇到同样的问题。

我的症状与OP相同。我会运行PHP脚本,它将通过shell_execute启动Expect脚本,然后它将永远挂起。问题原来是由于在Expect脚本运行时向apache用户询问了以下问题:

  

主机'xx.xx.xx.xx的真实性   (xx.xx.xx.xx)'无法建立。   RSA密钥指纹是xxxxx。你是   确定你想继续连接   (是/否)?

当我从命令行运行脚本时,这个问题不会出现,因为我认为只有主机添加到主机列表时才会询问一次。

要解决此问题,我在输入密码的地方之前添加了此代码:

expect "*you sure you want to continue*"
send -- "yes\r"

这导致了这个(我的PHP脚本返回了Expect脚本的所有输出):

  

主机'xx.xx.xx.xx的真实性   (xx.xx.xx.xx)'无法建立。   RSA密钥指纹是xxxxx。你是   确定你想继续连接   (是/否)?   是无法将主机添加到已知主机列表(/var/www/.ssh/known_hosts)。

然而,在此之后,密码提示出现并正确输入密码。从那时起,Expect脚本运行良好。

答案 3 :(得分:0)

另一个常见的问题是,当您运行该命令时,您与apache运行命令时的用户不同。通常,出于安全原因,用户apache的运行非常有限。

例如。 apache用户可能没有安装正确的路径。使用绝对路径期望,而不是相对。你可以通过运行'which expect'来找到它。

尝试'su'到同一个用户apache运行(在apache conf文件中查找'User'命令或只是浏览'ps aux')并运行命令并查看你得到的错误。

答案 4 :(得分:0)

PHP用于执行命令的“用户”或“组”可能没有足够的权限在脚本中执行一个cmd(甚至可能期望自己)。您是否尝试使用 sudo 以与您一直在测试的用户身份运行脚本?

答案 5 :(得分:0)

你在运行mod___php还是suPHP?
mod_php以Apache用户身份运行脚本,因此尝试su到apache用户,然后从shell“php scriptname.php”运行php脚本,看看它是否正常工作。
如果你使用suPHP,那么su给你设置apache的用户来修改这些脚本,然后使用相同的“php scriptname.php”并检查输出。

答案 6 :(得分:0)

小心期望在你输入你的下一个命令之前你等待了很长时间,并且你的所有变量都是正确的。格雷格使用2>& 1的指针为我省去了很多麻烦。

尝试运行

passthru("expect -d scripts/sshtest.exp $module");

-d将拯救你的生命。

答案 7 :(得分:0)

  1. 如果您使用的是exec而不是passthru,请以这种方式执行: exec(“/ bin / bash -c”命令'> logfile_to_read_or_include_next“);

  2. 如果您想使用衍生的流程弄乱您的系统:

  3. 编写一个perl / c脚本,用于处理您的请求。

    #!/usr/bin/perl -w
    use HTTP::Daemon;
    use HTTP::Status;
    use strict;
      my $d = HTTP::Daemon->new(LocalPort => 10050) || die;
      print "Please contact me at: <URL:", $d->url, ">\n";
      while (my $c = $d->accept) {
          while (my $r = $c->get_request) {
              if ($r->method eq 'GET' and $r->uri->path =~/addRequest-(.*)$/) {
                    # variable $1 now has your request.
                     my $rq = $1; # wash me!
                    # assign it a #ID, 
                     my $id = "id".time().rand(100);
                     &run_in_another_thread($rq,$id);
                  $c->send_responce($id);
              } elsif ($r->method eq 'GET' and $r->uri->path =~/seeRequest-(.*)$/) {
                 $c->send_responce( &get_result_for_id($1) );
              }
              else {
                  $c->send_error(RC_FORBIDDEN)
              }
          }
          $c->close;
          undef($c);
      }
    }
    
    sub run_in_another_thread {
     my ($rq,$id) = @_;
     my $evil = threads->create( sub { qx"/bin/bash -c '$rq' > logfile_$id.log" # start process
      }->detach();
    }
    
    sub get_result_for_id {
     my ($id) = @_;
     return qx"cat logfile_$id.log";
    }
    

    接下来,从你的代码中获取127.0.0.1/addRequest-expect,并且瞧..