PHP @ exec sessizce başarısız oluyor

9 Cevap php

Bu beni deli ediyveya. Benim PHP web uygulaması için bir pencere kutusunda bir komut satırı deyimini yürütmek çalışıyveyaum. Bu Windows XP, IIS5.1 üzerinde çalışıyveya. Web uygulaması gayet iyi çalışıyveya, ama belirli bir contactenated değişken ile çalışmak) (exec @ alınamıyveya. Benim komut inşaat bu gibi görünüyveya:

$cmd = ($config->svn." cat ".$this->repConfig->svnParams().quote($path).' -r '.$rev.' > '.quote($filename));

Bu komut aşağıdaki dize oluşturduğunda, yukarıda olduğu gibi çalışmaz:

svn --non-interactive --config-dir /tmp cat "file:///c:/temp/test/acccount/dbo_sproctest.sql" -r 1 > "C:\Inetpub\sites\websvn\temp\wsv5B45.tmp"

Ben / benim kendi komut satırına bu kopyalayıp yapıştırın, bu iyi çalışıyveya.

Eğer yerine değişkeni ile eklerken çok aynı yol, çalışır ben sert kodu! Ben dosya adı tırnak ile ve olmadan denedim. Ben tüm komutuyla tırnak ile ve olmadan denedim. Ben diğer dizinleri denedim. I () exec bir çıkış Paramtre geçen denedim, ve boş geri geliyveya (Array ()). Ben bir dosyaya komut hata akımının çıkış yönlendirme denedim, ve bu hata çıktı dosyası oluşturulur geçmez.

Ben belki bir concieve olabilir tek şey exec () sessizce başarısız olmasıdır. Ben burada yanlış yeryüzünde ne yapıyveyaum? Ben zveya kod Eğer dosya yolu, aynı dir yapısını ve dosya adını kullanarak, iyi çalışıyveya. Ben yapmazsam, öyle değil.

Belki dosya yolu eğik çizgi () düzgün kaçtı olmak değil, ama ben tek tırnak ile elle yapmak zaman kaçış dizileri kabul edilmez?

UPDATE:

Ben exec kapalı @ aldı ve hala herhangi bir hata göremiyveyaum.

Ben hala, SVN hiç şans tam yolunu verdi. Bu komut çok uzun elle kedi için dosya hedef belirlemek gibi olmayan tam yolu SVN ile daha önce iyi çalıştı unutulmamalıdır.

Update 2: RE: Kieth

Ben hem deneyerek exec arıyveyaum:

exec($cmd);

veya

exec($cmd, $out);

Benim php.ini zaten safe_mode = 0 vardı.

I added errveya_repveyating(E_ALL); and didn't see anything new

If I echo (veya print_r) my exec call, I am not actually seing anything

If I echo (veya print_r) my exec call when included an output var, I get an empty arr

Update 3

Ben escapeshellcmd hem denedim ve boşuna (iyi bir fikir olsa da) escapeshellarg.

Ben dosyayı çağırarak aracılığıyla oluşturulan ediliyor eklemek gerekir

tempnam("temp", "wbsn");

The fact that it wveyaks just fine if I manually specify the string instead of letting it be generated by tempname seems to suggests that the source of the problem, but I can't figure out how. I did a comparison of the manual string with the one generated, and it came back as a match.

9 Cevap

@ PHP'nin hata bastırma operatörü çünkü @exec, her zaman, sessizce başarısız olur.

Emin değil Windows madem bu size yardımcı olacak ve Linux üzerinde, ama ben PHP exec () dan sessiz hataları bu aynı sorun koştu eğer. Ben (NConvert) çıkarmaya çalışıyordu komut dışarı standart değil, standart hata akımına kendi hata iletileri gönderir anladım. Yani eklendi

2>&1

komut satırının sonunda geri standart akış benim hata yönlendirmek. Sonra NConvert bana bir izin engellendi hata veriyor olduğunu görebiliyordu.

Bu PATH kullanıcı hesabınız vs php komut aynı olmadığını olabilir. @ Kaldırmayı deneyin ve bir hata atmak için çalışıyor bakın.

Buna ek olarak, SVN yürütülebilir tam dosya sistemi yolunu koyarak denemek isteyebilirsiniz.

Peki, @ çalışmıyor kaldırarak eğer, çalıştırdığınız kod parçasının başında bu dahil deneyin:

error_reporting(E_ALL);

Yani bu sizin php.ini dosyasında aşağı veya özürlü çevirdi zorunda sadece durumda, tam hata raporlama döneceğiz.

Ben size aradığınız tam olarak nasıl bize göstermek olabilir sanmıyorum exec()? Ayrıca yanlışlıkla güvenli modda komut çalışmadığından emin olmak için kontrol eder misiniz? Eğer exec() dönüyor ne yankılanıyor, ve eğer öyleyse, ne dönüyor?

Eğer echo exec ("dir") veya exec () tüm çalışma olup olmadığını görmek için basit bir şey denediniz mi?

Shell exec sorunları hata ayıklama komutun başında bir "echo" yerleştirmek için çok yararlı bir hile. Eğer bir yerde standart çıktıyı görebilirsiniz emin olun.

Bu, herhangi bir bariz sorunlar için komutu inceleyelim olacaktır. Belki de beklenmedik genişleyen bir joker var, ya da belki alıntı kabuk tam olarak doğru değildir. Echo bu görelim, ve bunu düzgün çalışıp çalışmadığını görmek için başka bir kabuk içine yankılandı komutunu kesme ve yapıştırma yapabilirsiniz.

Ben başka bir yanıt ekleyerek büyük bir hayranı değilim, ama ben sadece benim önceki yanıtı düzenlemek eğer, bunu görmüyor olabilir.

escapeshellcmd ve escapeshellarg: PHP komut kabuk için bazı özel kaçan komutları vardır.

I think Eğer tüm $ cmd çevresindeki escapeshellcmd kullanmak gerekir, ama emin değilim.

Ben ne oluyor bilmiyorum, ama en azından bir çözüm var.

Bu çalışır:

$tmp = tempnam("./", "wbsn");
$filename = dirname($tmp).'\\temp\\'.basename($tmp);

Bu, ancak, ama ben (yeni bir tempnam beri fark dosya adı ()) aynı yolu üretmek bekleniyor olurdu değil.

$tmp = tempnam("temp", "wbsn");

Ayrıca, bu ben de aynı şeyi üretmek için beklediğiniz, hangi işe yaramazsa:

$tmp = tempnam("temp", "wbsn");
$filename = dirname($tmp).'\\'.basename($tmp);

Bu çözümlerin tüm 3 appear aynı dosya yolları üretmek için, ama benim exec kullanıldığında yalnızca ilki aslında çalışır. Öyle değil neden no ipucu var.

Bu her 3 görsel inceleme (eko) (tabii ki farklı dosya hariç) aynı yolları oluşturmak için görünür. Bu 3 her dirname bir dize karşılaştırma (), bir maç olarak gösterir. Ben anlaşma ne olduğunu hiçbir ipucu var, ama ilk geçici bir çözüm değildir.

Benim tavsiyem WIN geçiş olacak, linux için IIS, ama alternatif olarak bu deneyebilirsiniz:

function exec_alt($cmd) {
    exec($cmd, $output);
    if (!$output) {
        /**
         * FIXME: for some reason exec() returns empty output array @mine,'s machine.
         *        Somehow proc_open() approach (below) works, but doesn't work at
         *        test machines - same empty output with both pipes and temporary
         *        files (not we bypass shell wrapper). So use it as a fallback.
         */
        $output = array();
        $handle = proc_open($cmd, array(1 => array('pipe', 'w')), $pipes, null, null, array('bypass_shell' => true));
        if (is_resource($handle)) {
            $output = explode("\n", stream_get_contents($pipes[1]));
            fclose($pipes[1]);
            proc_close($handle);
        }
    }
    return $output; }