Administrare server open source

Platforma de hosting cu software liber, gratuit, open source.

Comentariile sunt închise pentru Rularea de comenzi UNIX din PHP

Este util de foarte multe ori, in mod special in cazul in care serverul web ruleaza sub UNIX, sa rulam diferite comenzi din scripturile PHP. Este mult mai convenabil, de exemplu, sa rulam comanda UNIXwhois 4.2.2.2” ca sa aflam informatii despre IP-ul respectiv decat sa ne facem propria aplicatie bazata pe socket-uri care in majoritatea cazurilor nu e nici de departe la fel de bine optimizata cum e comanda whois din UNIX. De asemenea sa implementam in PHP diferite functionalitati care tin in mare parte de sistemul de operare ar insemna sa reinventam roata si sa facem o munca inutila in plus.

Dezvoltatorii PHP au pus la dispozitie mai multe metode de rulare a comenzilor, majoritatea fiind functii cu care suntem familiarizati din alte limbaje de scripting sau programare. Metodele de rulare a comenzilor difera in functie de necesitati si comoditate. Mai jos ofer exemple pentru doar cateva din aceste metode si anume: operatorul backtick si functiile shell_exec(), exec() si system().

In exemplele de mai jos am preferat sa afisez totul in format text/plain din comoditate. Functia header() folosita nu are nici o legatura cu rularea comenzilor.

1. Operatorul backtick este preferat de majoritatea programatorilor datorita usurintei in utilizare. Pentru rularea unei comenzi se introduce comanda, cu parametri aferenti daca e cazul, intre apostroafe ( ` ). Trebuie observat caracterul apostrof ( ` ) folosit pentru backtick si nu trebuie confundat cu ghilimelele simple ( ‘ ) sau ghilimelele duble ( ” ). Un exemplu de utilizare gasiti mai jos:

< ?php
    header('Content-type: text/plain');
    $buf = `/bin/ls -a`;
    echo $buf;
?>

Codul de mai sus executa comanda „/bin/ls -a” pentru afisarea continutului folderului curent. Rezultatul este pastrat in variabila $buf in format text care poate fi apoi prelucrata si afisata cu echo() sau print(). Trebuie retinut ca atunci cand PHP este configurat sa ruleze in safe_mode operatorul backtick este dezactivat.

2. Functia shell_exec() este identica cu operatorul backtick. Modul de utilizare si operare este acelasi, in afara de apelare (functie, nu operator) nu exista nici o diferenta. Este bine de stiut ca atunci cand functia shell_exec() este blocata din php.ini nu va functiona nici operatorul backtick.

< ?php
    header('Content-type: text/plain');
    $buf = shell_exec('ls -a');
    echo $buf;
?>

3. Orice comanda in UNIX returneaza un raspuns care poate fi verificat citind din shell variabila de mediu $? si care ne spune daca executia comenzii s-a finalizat cu succes. Daca avem nevoie de rezultatul comenzii rulate putem folsi functia system() care accepta un al doilea parametru, pe langa primul care e comanda ce trebuie rulata, in care se stocheaza valoarea returnata dupa rularea functiei. Un exemplu de utilizare se gaseste mai jos:

< ?php
    header('Content-type: text/plain');
    system("/bin/ls -a",$retval);
    echo "Retval:\n$retval";
?>

In $retval se va pastra valoarea returnata la finalizarea rularii comenzii. Un dezavantaj al acestei functii este faptul ca rezultatul este afisat automat fara a avea posibilitatea de a-l suprima sau de a-l prelucra inainte de a fi afisat. Pentru a rezolva aceasta problema se poate folosi functia exec().

4. Functia exec() este asemanatoare cu functia system(). Diferenta este ca rezultatul nu se afiseaza automat ci e salvat in variabila data in al doilea parametru de apelare. Dupa rulare variabila din al doilea parametru va contine un array care are ca elemente fiecare rand returnat de comanda rulata. Valoarea returnata de functia exec() este ultimul rand afisat de rularea comenzii. Un exemplu de utilizare se gaseste mai jos:

< ?php
    header('Content-type: text/plain');
    $buf = exec("/bin/ls -a",$output,$retval);
    print_r($output);
    echo $buf;
    echo "Retval:\n$retval";
?>

Pentru afisarea array-ului din $output am folosit functia print_r() dar acesta se poate prelucra folosind metodele clasice de utilizare a array-urilor.

Acestea ar fi metodele cele mai folosite pentru rularea unei comenzi. Pentru rularea comenzilor se pot folosi si functiile pcntl_exec(), proc_open() sau alte metode avansate de rulare, dar in majoritatea cazurilor nu veti avea nevoie de mai mult decat e afisat mai sus.

De asemenea e important de retinut ca aceste functii nu au restrictii. Daca PHP e rulat in mod DSO iar din php.ini sau httpd.conf contul de hosting este restrictionat la utilizarea unui director folosind php_openbasedir, restrictia nu va avea efect asupra comenzilor UNIX rulate. Adica pot fi accesate fara probleme toate resursele la care are acces utilizatorul care ruleaza serverul web (nobody in majoritatea cazurilor).

Este bine de retinut ca aceste functii chiar daca sunt utile pot reprezenta un pericol major pentru securitatea serverului si in cazul in care nu sunt folosite trebuie dezactivate pentru a preveni astfel atacurile bazate pe web.

PHP

Comments are closed.