Comment `sudo` search-t-il le path d'access pour les exécutables?

J'utilise rubygems (1.3.7) avec des gemmes nécessitant des privilèges root sur Ubuntu 10.10. Lorsque je compare mon installation à un ubuntu 9.10 avec l'installation de rubygems 1.3.6, je vois la différence suivante dans l' gem environment :

1.3.7 / 10.10 - EXECUTABLE DIRECTORY: /var/lib/gems/1.8/bin

1.3.6 / 09.10 - EXECUTABLE DIRECTORY: /usr/bin

La sortie est la même si j'utilise sudo ou non. Pour corriger cela (je ne sais pas pourquoi il est différent en premier lieu), j'ai essayé de modifier ma variable de path.

Ma question est, où sudo cherche-t-il des exécutables? Si j'installe une gemme (en utilisant sudo ), l'exécutable est placé dans le path /var , évidemment. J'ai ajouté ce path d'access à mes ~/.profile et /etc/environment , mais je ne peux pas get sudo pour exécuter les exécutables.

Si je cours:

  • $ gemname il exécute mon outil correctement.
  • $ sudo gemname il me dit simplement que la command not found .
  • $ sudo echo $PATH il montre le path correct.
  • $ sudo -i gemname il fonctionne correctement.
  • $ sudo sudo -V montre que le path d'access est conservé.

Est-ce que sudo honneur ~/.profile et / ou /etc/environment ? Dans l'affirmative, pourquoi ne peut-il pas find mon file exécutable alors que le directory est affiché dans la variable d'environnement $PATH ?

J'ai lu la documentation de sudo , j'ai également cherché et examiné une tonne de sujets sur stackoverflow et serverfault (par exemple, comment replace une variable d'environnement PATH dans sudo?, Mais mon exemple montre que $PATH contient le path correct), mais Ils ne montrent jamais comment exécuter un bijou via sudo .

Notez que, dans votre troisième command, votre shell développe $PATH avant que sudo ne le voie, et la sortie est le path de votre shell, et non le PATH que sudo voit. Ce que vous voulez, c'est quelque chose comme sudo echo \$PATH ou sudo sh -c 'echo $PATH' .

Au-delà, regardez la section NOTES DE SÉCURITÉ de la page de manuel sudo(8) . Je crois que Ubuntu construit sudo avec l'option de construction SECURE_PATH. Recherchez la ligne «Valeur à annuler la ligne $ PATH avec" dans la sortie de sudo sudo -V .

sudo -i simule une connection initiale, et ainsi lire des files comme .profile (bien que les files qu'il lit dépendent de la shell de la racine). Sans -i , il hérite des variables d'environnement préservées de l'environnement de son appelant, avec l'assainissement PATH que j'ai mentionné ci-dessus.

Quant à la raison pour laquelle le path a changé en premier lieu, je soupçonne que le changement a été un choix délibéré de la part des développeurs. Voir plus de discussion sur bugs.debian.org .

Passons par pièces:

  • gemname, il exécute correctement mon outil.

C'est bon 🙂

  • sudo gemname, il me dit simplement que la command n'a pas été trouvée.

gemname n'est pas dans votre $PATH

  • sudo echo $ PATH il montre le path correct.

C'est cool: l'expansion variable se produit avant que bash exécute le programme. Donc, lorsque vous exécutez cela, il se développe à votre $PATH user avant d' appeler sudo, de sorte que la ligne passée à sudo ressemble plus à:

 $ sudo echo "/usr/bin:/bin:" 
  • sudo -i gemname, il fonctionne correctement.

sudo -i s'exécute en tant que shell de connection et honore .profile et / ou .login . Comme le dit la page man :

Il initialise également l'environnement, laissant DISPLAY et TERM inchangés, configurant HOME, MAIL, SHELL, USER, LOGNAME et PATH, ainsi que le contenu de / etc / environment sur les systèmes Linux et AIX. Toutes les autres variables d'environnement sont supprimées.