PHP shell_exec () vs exec ()


345

J'ai du mal à comprendre la différence entre shell_exec()et exec()...

Je l'ai toujours utilisé exec()pour exécuter des commandes côté serveur, quand devrais-je utiliser shell_exec()?

Est-ce shell_exec()juste un raccourci pour exec()? Il semble que ce soit la même chose avec moins de paramètres.


2
bon exemple pour voir les différences est d'essayer ces commandes: date, whoami, ifconfig, netstat.

Il y a aussi d'autres fonctions: system (), passthru ()… voir cette question connexe , et en particulier cette réponse .
Gras Double

1
Duplication possible de PHP exec () vs system () vs passthru ()
jww

Réponses:


353

shell_execrenvoie tout le flux de sortie sous forme de chaîne. execrenvoie la dernière ligne de la sortie par défaut, mais peut fournir toutes les sorties sous forme de tableau spécifié comme deuxième paramètre.

Voir


21
Si vous avez besoin de la valeur de sortie ET de toutes les sorties, vous êtes probablement encore mieux d'utiliser "exec" plutôt que "shell_exec". Dès que vous passez le paramètre de sortie à "exec", il sera rempli avec chaque ligne de la sortie, il me semble que "exec" peut tout de "shell_exec" et plus :)
Preexo

4
@ daniel-a-white Je sais que c'est une ancienne, mais elle est populaire, vous devez donc modifier votre réponse pour refléter le commentaire fait par @preexo - exec () a également la possibilité de renvoyer la sortie entière si vous utilisez ses paramètres facultatifs . De plus, sans relation, quelqu'un devrait comparer les deux commandes pour voir laquelle est la meilleure parce que @preexo a dit " il me semble qu'il exec()peut [faire] tout shell_exec()[peut,] et plus :) "
SimpleAnecdote

77

Voici les différences. Notez les nouvelles lignes à la fin.

> shell_exec('date')
string(29) "Wed Mar  6 14:18:08 PST 2013\n"
> exec('date')
string(28) "Wed Mar  6 14:18:12 PST 2013"

> shell_exec('whoami')
string(9) "mark\n"
> exec('whoami')
string(8) "mark"

> shell_exec('ifconfig')
string(1244) "eth0      Link encap:Ethernet  HWaddr 10:bf:44:44:22:33  \n          inet addr:192.168.0.90  Bcast:192.168.0.255  Mask:255.255.255.0\n          inet6 addr: fe80::12bf:ffff:eeee:2222/64 Scope:Link\n          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1\n          RX packets:16264200 errors:0 dropped:1 overruns:0 frame:0\n          TX packets:7205647 errors:0 dropped:0 overruns:0 carrier:0\n          collisions:0 txqueuelen:1000 \n          RX bytes:13151177627 (13.1 GB)  TX bytes:2779457335 (2.7 GB)\n"...
> exec('ifconfig')
string(0) ""

Notez que l'utilisation de l' opérateur backtick est identique à shell_exec().

Mise à jour: je devrais vraiment expliquer ce dernier. En regardant cette réponse des années plus tard, même je ne sais pas pourquoi cela est resté vierge! Daniel l'explique ci-dessus - c'est parce execque ne renvoie que la dernière ligne, et ifconfigla dernière ligne est vide.


que se passe-t-il s'il y a une erreur avec la commande ..? J'obtiens l'erreur / Aucun fichier ou répertoire de ce type, mais comment puis-je le capturer dans une variable ????
Happy Coder

@AlwinAugustin: Hein? Pourrait être écrit à STDERR. Essayez d'ajouter 2>&1à la fin de votre commande pour rediriger STDERR vers STDOUT si vous êtes sur une machine Linux.
mpen

Je l'ai ajouté également. Mais je reçois toujours 0 comme valeur. J'ai utilisé une commande wc -l et si le fichier n'est pas là, j'ai besoin d'obtenir le message d'erreur disant Aucun fichier ou répertoire.
Happy Coder

50

shell_exec- Exécuter la commande via le shell et retourner la sortie complète sous forme de chaîne

exec - Exécutez un programme externe.

La différence est que shell_execvous obtenez la sortie comme valeur de retour.


4
Beau résumé succinct! Il faut tout de même noter que execretourne la dernière ligne de la sortie. Si vous le souhaitez, vous pouvez éventuellement transmettre un tableau comme deuxième paramètre pour capturer la sortie complète, et un entier comme troisième paramètre pour capturer la valeur de retour de la commande shell, qui peut être utilisée pour la vérification des erreurs. Le plus gros inconvénient shell_execest qu'il retourne null si la commande échoue OU s'il ne produit aucune sortie, donc sa valeur de retour ne peut pas être utilisée de manière fiable pour la vérification des erreurs.
Sean the Bean

38

Quelques distinctions qui n'ont pas été abordées ici:

  • Avec exec (), vous pouvez passer une variable param optionnelle qui recevra un tableau de lignes de sortie. Dans certains cas, cela peut gagner du temps, surtout si la sortie des commandes est déjà tabulaire.

Comparer:

exec('ls', $out);
var_dump($out);
// Look an array

$out = shell_exec('ls');
var_dump($out);
// Look -- a string with newlines in it

Inversement, si la sortie de la commande est xml ou json, avoir chaque ligne dans un tableau n'est pas ce que vous voulez, car vous devrez post-traiter l'entrée sous une autre forme, alors dans ce cas, utilisez shell_exec .

Il convient également de souligner que shell_exec est un alias pour l'opérateur backtic, pour ceux utilisés pour * nix.

$out = `ls`;
var_dump($out);

exec prend également en charge un paramètre supplémentaire qui fournira le code retour de la commande exécutée:

exec('ls', $out, $status);
if (0 === $status) {
    var_dump($out);
} else {
    echo "Command failed with status: $status";
}

Comme indiqué dans la page de manuel shell_exec, lorsque vous avez réellement besoin d'un code retour de la commande en cours d'exécution, vous n'avez pas d'autre choix que d'utiliser exec.


3
De plus: execvous permet d'obtenir le code retour de la commande (via le &$return_varparamètre), tout en shell_execne fournissant aucun moyen de l'obtenir.
Mark Amery

Bien que la réponse acceptée soit également correcte, à mon avis, cette réponse est plus importante. La meilleure réponse serait probablement la combinaison des deux.
UncaAlby
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.