[英]How to use an expect script from php webpage?
當我嘗試在我的debian上從php5執行程序時,網頁凍結,該程序無濟於事。 當我從命令行調用它時,此腳本有效。 安全模式已禁用。 回聲標准輸出不起作用(由於凍結)。 我在google上讀到了一些答案,其中顯示了www權限,但是如果有人在這里有快速簡單的響應...
如何調試呢?
exec("expect scripts/sshtest.exp $module");
#!/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
嘗試
passthru("expect scripts/sshtest.exp $module 2>&1");
2>&1
將stderr
重定向到stdout
,使用passthru
而不是exec
將為您提供所有輸出。
為什么要使用期望? 將rsync設置為使用公用/專用密鑰(請參閱http://troy.jdmz.net/rsync/index.html ),您將不必使用期望輸入的密碼。
我遇到了同樣的問題,這讓我發瘋。 我參加聚會有點晚了,但我想我會發布解決問題的解決方案,以防其他人遇到此問題並遇到相同的問題。
我的症狀與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腳本運行良好。
另一個常見問題是,當您運行命令時,您與apache運行命令時的用戶是不同的用戶。 通常,出於安全原因,用戶apache的運行方式非常有限。
例如。 apache用戶可能未安裝正確的路徑。 使用絕對路徑期望,而不是相對路徑。 您可以通過運行“哪個期望”來找到它。
嘗試“ su”到與apache運行相同的用戶(在apache conf文件中查找“ User”命令,或者只是瀏覽“ ps aux”)並運行該命令,看看會遇到什么錯誤。
PHP用於執行命令的“用戶”或“組”可能沒有足夠的權限來執行腳本中的一個cmd(甚至期望自己執行)。 您是否嘗試過使用sudo以與您測試過的同一用戶身份運行腳本?
您正在運行mod___php還是suPHP?
mod_php以Apache用戶身份運行腳本,因此請嘗試使用apache用戶,然后從外殼“ php scriptname.php”運行php腳本,以查看其是否正常運行。
如果您使用suPHP,則將su交給您的用戶,在該用戶下您已設置apache來調整這些腳本,並調整相同的“ php scriptname.php”並檢查輸出。
請謹慎對待php,因為它會在輸入下一個命令之前等待足夠長的時間,並且所有變量都是正確的。 Greg使用2>&1的指針為我節省了很多麻煩。
嘗試跑步
passthru("expect -d scripts/sshtest.exp $module");
-d將拯救您的生命。
如果您使用的是exec而不是passthru,請按照以下方式進行操作:exec(“ / bin / bash -c'command'> logfile_to_read_or_include_next”);
如果您想讓產生的進程使您的系統混亂:
編寫一個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,然后瞧。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.