2012-08-30 13 views
11

Il comando exec non funziona sul mio server, non fa nulla, ho disattivato safe_mode e verificato che tutti i comandi della console funzionano, ho provato con percorsi assoluti. Ho controllato le autorizzazioni sulle applicazioni e tutte le applicazioni di cui ho bisogno hanno le autorizzazioni di esecuzione. Non so cos'altro fare, ecco la carrellata dei codici che ho provato.Come posso eseguire il debug di problemi exec()?

echo exec('/usr/bin/whoami'); 

echo exec('whoami'); 

exec('whoami 2>&1',$output,$return_val); 
if($return_val !== 0) { 
    echo 'Error<br>'; 
    print_r($output); 
} 

exec('/usr/bin/whoami 2>&1',$output,$return_val); 
if($return_val !== 0) { 
    echo 'Error<br>'; 
    print_r($output); 
} 

L'ultima due codici di visualizzazione:

Error 
Array () 

Ho contattato il servizio del server e non mi posso fare a meno, non sanno il motivo per cui il comando exec non funziona. Perdona il mio cattivo inglese.

+0

Cosa intendi con "non funziona"? Qualche errore? – Touki

+0

Hai provato error.log? – Rolice

+0

Impostazioni errore 'display_errors = 1' e' error_report = E_ALL'? (Nota che non dovresti visualizzare errori sui sistemi live. Disabilita, se hai finito) – KingCrunch

risposta

10

uno sguardo a /etc/php.ini, là sotto:

; This directive allows you to disable certain functions for security reasons. 
; It receives a comma-delimited list of function names. This directive is 
; *NOT* affected by whether Safe Mode is turned On or Off. 
; http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.disable-functions 
disable_functions = 

assicurarsi che exec non è elencato in questo modo:

disable_functions=exec 

In tal caso, rimuoverlo e riavviare l'apache.

Per un facile debug di solito mi piace eseguire il file php manualmente (è possibile richiedere più errori senza impostarlo nel file principale ini). Per fare in modo aggiungere l'intestazione:

#!/usr/bin/php 
ini_set("display_errors", 1); 
ini_set("track_errors", 1); 
ini_set("html_errors", 1); 
error_reporting(E_ALL); 

all'inizio del file, dare autorizzazioni utilizzando chmod +x myscript.php ed eseguirlo ./myscript.php. È molto attenta soprattutto su un server occupato che scrive molto sul file di registro.

EDIT

suona come un permessi problema. Crea uno script bash che faccia qualcosa di semplice come echo "helo world" e prova ad eseguirlo. Assicurati di disporre delle autorizzazioni per il file e per la cartella contenente il file. devi solo fare chmod 755 solo per il test.

+0

'disable_functions' è vuoto nel mio' php.ini', eseguo lo script come suggerito e la console non mostra nulla. – carcargi

+0

@Necroside risposta aggiornata. – Kuf

+0

Grazie mille, questo ha fatto il trucco, il problema era che in qualche modo (dato che il mio cliente ha accesso al server e pensa di essere un esperto XD), ha copiato e modificato le autorizzazioni delle app. Li ho spostati nella cartella originale e configurato di nuovo il percorso, ora tutto funziona, l'ho trovato mentre testavo i permessi dell'applicazione. Grazie. – carcargi

4

È possibile retreive le uscite e il codice dei comandi exec tornare, thoses forza contiene informazioni che spiegherebbero il problema ...

exec('my command', $output, $return); 
+0

Ho appena aggiunto il codice alla domanda e non ho notato questa risposta, mostra solo questo. 'Errore Matrice()' – carcargi

+0

E cosa contiene la variabile $ return_val? – YohannP

5

Poiché si sta abbandonando il contesto PHP nella shell nativa, si verificheranno numerosi problemi di debug.

Il migliore e il più infallibile che ho usato in passato è scrivere l'output dello script in un file di registro e metterlo in coda durante l'esecuzione di PHP.

<?php 
shell_exec("filename > ~/debug.log 2>&1"); 

Poi in un guscio separata:

tail -200f ~/debug.log 

Quando si esegue lo script PHP, i vostri errori e di uscita dalla vostra chiamata shell verranno visualizzati nel file debug.log.

0

Alcune note in più.

  • Per il debugging avvolgere sempre il tuo exec funzione/shell_exec in var_dump().

  • error_reporting(-1); dovrebbe essere accesa, come dovrebbe essere display_errors, come ultima risorsa, anche set_error_handler("var_dump"); - anche solo per vedere se lo stesso PHP non ha invocato execvp o altro.

  • Utilizzare 2>&1 (unire le shell STDERR al flusso STDOUT) per capire perché un richiamo non riesce.
    Per alcuni casi potrebbe essere necessario per avvolgere il vostro comando in un ulteriore invocazione della shell:

    // capture STDERR stream via standard shell 
    shell_exec("/bin/sh -c 'ffmpeg -opts 2>&1' "); 
    

    Altrimenti il ​​file di registro reindirizzare come consigliato dal @ Mike è l'approccio più raccomandabile.

  • Alternare tra le varie funzioni di exec per scoprire altrimenti i messaggi di errore. Mentre la maggior parte essi fanno la stessa cosa, i percorsi di ritorno uscita variano:

    1. exec() → o restituisce l'output come risultato della funzione, o tramite l'$output paramater opzionale.
      Fornisce anche un parametro $return_var, che contiene il codice errno/exit dell'applicazione o shell di esecuzione. Si potrebbe ottenere:

      • ENOENT (2) - Nessun file
      • EIO (127) - Errore di IO: file non trovato
    2. shell_exec() → è ciò che si desidera eseguire per lo più per le coperture espressioni di stile.
      Assicuratevi di assegnare/stampare il valore di ritorno ad es. var_dump(shell_exec("..."));

    3. `` linea backticks → sono identiche a shell_exec.

    4. system() → è simile a exec, ma restituisce sempre l'uscita come risultato della funzione (stamparlo!). Inoltre consente di acquisire il codice del risultato.

    5. passthru() → è un'altra alternativa a exec, ma invia sempre qualsiasi risultato STDOUT al buffer di output di PHP. Che spesso lo rende il wrapper exec più adatto.

    6. o superiore proc_open() → consentire di acquisire individualmente STDOUT e STDERR.

  • maggior parte degli errori di shell finiscono in phps o Apache error.log quando non è reindirizzato. Controlla il tuo syslog o il registro di Apache se nulla produce utili messaggi di errore.

I problemi più comuni che affliggono i nuovi arrivati ​​PHP/LAMP sono:

  • come detto da @Kuf: per i piani di webhosting obsoleti, si poteva ancora trovare safe_mode o disable_functions abilitato. Nessuna delle funzioni exec di PHP funzionerà. (Migliore di trovare un fornitore di meglio, altrimenti indagare "CGI" -. Ma non installare il proprio interprete PHP mentre unversed)

  • Allo stesso modo può AppArmor/SELinux/Firejail a volte essere a posto. Quelle limitano ogni capacità delle applicazioni di generare nuovi processi.

  • Il binario previsto non esiste. Praticamente nessun webhost ha strumenti come ffmpeg preinstallato. Non puoi semplicemente eseguire comandi di shell arbitrari senza preparazione. Alcune cose devono essere installate!

    // Check if `ffmpeg` is actually there: 
    var_dump(shell_exec("which ffmpeg")); 
    
  • Il PATH è spento. Se hai installato strumenti personalizzati, dovrai assicurarti che siano raggiungibili. L'utilizzo di var_dump(shell_exec("ffmpeg -opts")) ricercherà tutti i percorsi comuni - o come Apache è stato detto/limitato (spesso solo /bin:/usr/bin).

    Verificare con print_r($_SERVER); cosa contiene il PERCORSO e se questo copre lo strumento che si desidera eseguire. Altrimenti potrebbe essere necessario adattare le impostazioni del server (/ etc/apache2/envvars), oppure utilizzare percorsi completi:

    // run with absolute paths to binary 
    var_dump(shell_exec("/bin/sh -c '/usr/local/bin/ffmpeg -opts 2>&1'")); 
    

    Questo è in qualche modo sovvertire il concetto di guscio. Personalmente non lo ritengo preferibile. Tuttavia, ha senso per motivi di sicurezza; inoltre per l'utilizzo di un'installazione personalizzata ovviamente.

  • Permessi

    1. Al fine di eseguire un binario su sistema BSD/Linux, si deve essere fatta "eseguibile". Questo è ciò che fa chmod a+x ffmpeg.

    2. Inoltre, il percorso di tali file binari personalizzati deve essere leggibile dall'utente Apache, in cui vengono eseguiti gli script PHP.

    3. Altre configurazioni contemporanee utilizzano PHP in modalità FPM (suexec + FastCGI), in cui il tuo account di web hosting equivale a ciò che viene eseguito da PHP.

  • di prova con SSH. Dovrebbe essere ovvio, ma prima di eseguire comandi tramite PHP, testarlo in una shell reale sarebbe altamente sensato. Sonda con ad es. ldd ffmpeg se ci sono tutte le dipendenze lib e se funziona diversamente.

  • valori di input (GET, POST, i nomi dei file, dati applicativi) che vengono passati come argomenti del comando in exec stringhe devono essere scappato con escapeshellarg().

    $q = "escapeshellarg"; 
    var_dump(shell_exec("echo {$q($_GET['text'])} | wc")); 
    

    In caso contrario, si verificheranno facilmente errori di sintassi della shell; e probabilmente sfruttare il codice installato in seguito ...

Problemi correlati