web-dev-qa-db-fra.com

Exécutable s'exécute sans Sudo mais pas avec sudo

J'ai installé xampp sur mon système à l'emplacement /opt/lampp. Après cela, j’ai ajouté l’emplacement php à ma variable de chemin à l’aide de

export PATH=$PATH:/opt/lampp/bin

Ainsi, lorsque je lance php -v à l'aide d'un terminal, je reçois le résultat attendu.

PHP 5.6.8 (cli) (built: Apr 20 2015 18:37:47) 
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies

Mais quand je lance Sudo php -v je reçois ceci:

Sudo: php: command not found

Je ne sais pas pourquoi cela se produit. Est-ce que je fais quelque chose de mal en l'ajoutant à la variable de chemin?

Modifier:

Cette question n'est pas une copie de Les variables d'environnement sont exécutées avec 'Sudo' , car dans cette question, zetah a demandé comment passer des variables arbitraires à une commande python. Ils peuvent exécuter python avec Sudo, mais je ne peux pas exécuter php avec Sudo.

Après cette réponse , j'ai ajouté le PATH à Sudo à l'aide de la commande suivante:

Sudo PATH=$PATH:/opt/lampp/bin php -v

mais je reçois la sortie comme avant:

Sudo: php: command not found

Après cette réponse , j’ai ajouté -E à Sudo, mais j’obtiens le même résultat:

$ Sudo -E php -v
Sudo: php: command not found
2
Mahendran Sakkarai

Pourquoi Sudo n'utilise pas votre PATH

La raison pour laquelle Sudo ignore votre variable PATH est qu’elle a son propre _secure_path_ et qu’elle est assez déterminée à l’utiliser.

Si vous _Sudo cat /etc/sudoers_ ou juste _Sudo grep secure /etc/sudoers_, vous verrez ce chemin est sur votre système. J'ai cette ligne:

_Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
_

Le but de Sudo '_secure_path_ est d'essayer de réduire le risque qu'un utilisateur disposant du privilège Sudo exécute (accidentellement) un code dangereux en tant que racine après la modification de son chemin, peut-être pour inclure annuaires locaux.

Il est possible d'éviter Sudo en utilisant le _secure_path_ en modifiant _/etc/sudoers_ pour commenter cette ligne, mais ce serait une mauvaise idée car cela supprime une mesure de sécurité. peut facilement contourner ce problème de différentes manières.

Obtenir Sudo pour utiliser votre PATH

Pour remplacer le _secure_path_ et faire en sorte que Sudo utilise votre PATH tel que défini actuellement, comme indiqué par un commentaire , vous pouvez utiliser:

_Sudo env PATH="$PATH" command_

Notez que l'indicateur _-E_ ou simplement l'attribution de la variable ne fonctionne pas (au moins sur Ubuntu).

_$ mkdir junk                            # create a test directory to add to PATH
$ echo "echo foo" > junk/useless        # create a harmless program
$ chmod u+x junk/useless                # make it executable
$ PATH="$PATH":~/junk                   # add directory to PATH
_

Lors de l'ajout à PATH, utilisez le chemin absolu (le shell développera _~_ avant d'affecter la variable). Je n'ai pas besoin de export (et cela n'aide en rien), parce que PATH est déjà exporté et que changer sa valeur entraînera également l'héritage de la modification par les processus enfants.

_$ useless
foo
$ Sudo useless
Sudo: useless: command not found
$ Sudo -E useless
Sudo: useless: command not found
_

On s’attend souvent à ce que cela fonctionne ... man Sudo dit:

_-E, --preserve-env
            Indicates to the security policy that the user wishes to
            preserve their existing environment variables.
_

Mais ça ne marche pas. L'indicateur _-E_ n'a aucun effet sur _secure_path_, qui est probablement un bogue .

_$ Sudo PATH="$PATH" useless
Sudo: useless: command not found
_

Cela n'affecte pas l'environnement propre de Sudo, qui a été défini conformément à la stratégie de sécurité, configuré par /etc/sudoers . Ceci inclut _env_reset_ et _secure_path_ comme valeurs par défaut sur Ubuntu, ce qui entraîne le chargement d’un environnement minimal et le paramétrage de PATH sur tout ce qui se trouve dans _secure_path_.

Si Sudo parvenait à trouver une commande appelée useless dans l'un de ses propres répertoires de chemin et l'exécutait, il passerait _PATH=$PATH_ dans son environnement comme illustré ici . Mais il n'utilisera pas lui-même la valeur donnée de PATH. La solution consiste à exécuter:

_$ Sudo env PATH="$PATH" useless
foo
_

Cette solution de contournement utilise la commande env pour définir PATH. Contrairement à Sudo, env utilise les variables données pour définir l'environnement, puis recherche l'argument de la commande et exécute la commande avec l'environnement modifié. Comme info (coreutils) env invocation dit:

Les modifications apportées à PATH prennent effet avant la recherche de la commande .

Définir le chemin

Lorsque vous avez modifié votre variable PATH pour inclure le répertoire _/opt/lampp/bin_, vous avez utilisé cette commande:

_export PATH=$PATH:/opt/lampp/bin
_

Cela serait efficace pour le Shell actuel et tous les processus enfants du Shell, tels que les shells appelés à partir de ce Shell. Lorsque vous avez quitté ce shell et tous ses enfants, la variable PATH modifiée a été complètement oubliée. Lorsque vous ouvrez un nouveau shell, vous retrouvez l'ancienne variable PATH qui n'inclut pas _/opt/lampp/bin_. Pour cette raison, la commande complète suggéré par mur ,

_Sudo env PATH="$PATH:/opt/lampp/bin" php -v
_

aurait été nécessaire si vous n’utilisiez pas encore un shell dans lequel vous aviez déjà ajouté _/opt/lampp/bin_.

Pour changer le chemin de façon permanente, vous devez éditer un fichier de configuration qui modifie votre environnement utilisateur ou qui est lu par les shells au démarrage. Vous pouvez ajouter une ligne pour affecter des variables d’environnement dans votre _~/.profile_, par exemple:

_PATH="$PATH:/opt/lampp/bin"
_

Ensuite, après vous être déconnecté et reconnecté (ou exécuté _source ~/.profile_ pour voir l'effet immédiatement), vous pourrez toujours exécuter

_php -v
_

ou

_Sudo env PATH="$PATH" php -v
_

sans d'abord ajuster votre PATH.

Des alternatives moins lourdes

Une solution plus pratique pourrait consister à créer un lien symbolique vers l'exécutable à un emplacement situé dans le _secure_path_ et dans le PATH par défaut, par exemple:

_Sudo ln -s /opt/lampp/bin/php /usr/local/bin/php
_

Vous n'aurez alors besoin de rien faire de spécial lorsque vous appelez la commande avec Sudo, ni de prendre des mesures pour ajuster votre PATH de façon permanente ou temporaire.

Si le programme que vous installez a un nom identique à celui d'un autre programme que les processus système peuvent tenter d'appeler, alors attribuez un nom différent au lien symbolique , pour éviter de confondre ces processus. Vous pouvez vérifier que le nom que vous souhaitez utiliser ne correspond pas déjà au nom d'une autre commande à l'aide de la commande type:

_$ type php
bash: type: php: not found
_

Donc, sur ce système, je peux créer une commande php sans craindre que rien ne se passe mal, pour le moment. Si j'installe d'autres programmes qui fournissent une commande php à l'avenir, je devrai peut-être repenser ma configuration.

Vous pouvez également créer un alias pour la commande et l'ajouter à votre _~/.bashrc_, par exemple:

_alias Sudo-php='Sudo env PATH="$PATH:/opt/lampp/bin/php"'
_

Vous pouvez ensuite (après avoir exécuté _source .bashrc_ ou ouvert un nouveau shell) exécuter

_Sudo-php
_

au lieu de _Sudo php_ pour exécuter ce programme en tant que root, et Sudo ne prétendra pas ignorer son emplacement.

Cet alias ne serait disponible que dans les shells interactifs, afin de ne pas confondre les autres programmes.

Bien sûr, il est possible de créer un alias pour juste Sudo afin qu'il utilise toujours votre PATH avec _alias Sudo='Sudo env PATH="$PATH"'_, mais c'est une mauvaise idée car cela rendrait le système moins sécurisé.

3
Zanna