J'ai un script dans / var/www/myscript.sh qui crée des dossiers et exécute la commande svn update
Pour mes projets. J'ai besoin d'exécuter ce script en l'appelant dans un fichier PHP dans le navigateur (ie Localhost/test.php). J'ai essayé d'utiliser les fonctions Shell_exec()
et exec()
mais cela n'a pas fonctionné. J'ai exécuté mon script Shell dans le terminal avec su www-data && ./myscript.sh
et cela a fonctionné. Que manque-t-il d'autre?
<?php
$output = Shell_exec("./myscript.sh");
?>
J'ai ajouté www-data ALL=(ALL) NOPASSWD:ALL
à/etc/sudoers et cela fonctionne, mais cela n'est pas très sûr. Y a-t-il une autre façon de procéder?
Plusieurs possibilités:
exec()
fonctionne, et uniquement sur les exécutables dans safe_mode_exec_dir
exec
et Shell_exec
sont désactivés dans php.iniexec(dirname(__FILE__) . '/myscript.sh');
Vous avez peut-être désactivé les privilèges d'exécution, la plupart des packages LAMP les ont désactivés. Vérifiez votre php.ini pour cette ligne:
disable_functions = exec
Et supprimez les entrées exec, Shell_exec s'il y en a.
Bonne chance!
Residuum a fourni une réponse correcte à la façon dont vous devriez demander à l'exécutable Shell de trouver votre script, mais en ce qui concerne la sécurité, il y a quelques points.
J'imagine que vous ne voulez pas que votre script Shell soit dans votre racine Web, car il serait visible par toute personne ayant un accès Web à votre serveur.
Je recommanderais de déplacer le script Shell à l'extérieur de la racine Web
<?php
$tempFolder = '/tmp';
$webRootFolder = '/var/www';
$scriptName = 'myscript.sh';
$moveCommand = "mv $webRootFolder/$scriptName $tempFolder/$scriptName";
$output = Shell_exec($moveCommand);
?>
En ce qui concerne:
j'ai ajouté www-data ALL = (ALL) NOPASSWD: ALL à/etc/sudoers fonctionne
Vous pouvez le modifier pour ne couvrir que les commandes spécifiques de votre script qui nécessitent Sudo. Sinon, si aucune des commandes de votre script sh ne nécessite l'exécution de Sudo, vous n'avez pas besoin de le faire de toute façon.
Essayez d'exécuter le script en tant qu'utilisateur Apache (utilisez la commande su pour basculer vers l'utilisateur Apache) et si vous n'êtes pas invité à Sudo ou si l'autorisation vous est refusée, etc., ça ira.
c'est à dire:
Sudo su Apache (or www-data)
cd /var/www
sh ./myscript
Aussi ... ce qui m'a amené ici, c'est que je voulais exécuter un script Shell multi-lignes à l'aide de commandes générées dynamiquement. Je voulais que toutes mes commandes s'exécutent dans le même shell, ce qui ne se produira pas en utilisant plusieurs appels à Shell_exec (). La réponse à celle-ci est de le faire comme Jenkins - créez votre ligne de commandes multi générée dynamiquement, placez-la dans une variable, enregistrez-la dans un fichier dans un dossier temporaire, exécutez ce fichier (en utilisant Shell_exec dans () php comme Jenkins est Java), puis faites ce que vous voulez avec la sortie et supprimez le fichier temporaire
... voila
Si vous avez un petit script que vous devez exécuter (j'avais simplement besoin de copier un fichier), j'ai trouvé beaucoup plus facile d'appeler les commandes sur le script PHP en appelant
exec("Sudo cp /tmp/testfile1 /var/www/html/testfile2");
et activer une telle transaction en modifiant (ou plutôt en ajoutant) une ligne d'autorisation aux sudoers en appelant d'abord Sudo visudo
et en ajoutant la ligne suivante à la toute fin
www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/testfile1 /var/www/html/testfile2
Tout ce que je voulais faire était de copier un fichier et j'ai eu des problèmes pour le faire à cause du problème de mot de passe root, et comme vous l'avez mentionné, je ne voulais PAS exposer le système à n'avoir aucun mot de passe pour toutes les transactions root.