2017-01-27 6 views
0

Edit # 1


Les "doubles" possibles à ce jour sont pas doublons. Ils testent l'existence de $FILE dans $PATH, plutôt que de fournir le chemin complet jusqu'au premier résultat valide; et la première réponse utilise commandes de ligne de commande, pas pur.Déterminer qui se déroulera binaire via execlp à l'avance

Original Question


De toutes les fonctions de la famille exec, il y a quelques-unes qui font $PATH plutôt que d'exiger des recherches d'un chemin absolu binaire à exécuter.

De man exec:

Le execlp(), execvp(), et les fonctions execvpe() en double les actions du shell dans la recherche d'un fichier exécutable si spécifié nom de fichier ne contient pas une barre oblique (/). Le fichier est recherché dans la liste des chemins d'accès au répertoire séparés par deux-points, spécifiée dans la variable d'environnement PATH. Si cette variable n'est pas définie, la liste de chemin par défaut correspond au répertoire courant suivi de la liste des répertoires renvoyés par confstr (_CS_PATH). (Ce confstr (3) appel renvoie généralement la valeur "/ bin:/usr/bin".)

est-il un moyen simple et direct, pour tester ce que le premier "chemin complet pour exécuter" sera évaluer à, sans avoir à parcourir manuellement tous les éléments dans la variable d'environnement $PATH, et en ajoutant le nom binaire à la fin du chemin? Je voudrais utiliser une approche «de facto standard» pour estimer le binaire à exécuter, plutôt que de réécrire une tâche qui a probablement déjà été implémentée plusieurs fois dans le passé.

Je me rends compte que ce ne sera pas une garantie, car quelqu'un pourrait potentiellement invalider cette vérification via un script buggé, des attaques TOCTOU, etc. J'ai juste besoin d'une approximation décente à des fins de test.

Merci.

+0

Possible copie de [C, test d'exécution si l'exécutable existe dans PATH] (http://stackoverflow.com/questions/8035372/c-runtime-test-if-executable-exists-in-path) – kaylum

+0

Pourquoi demander? Quel est le cas d'utilisation réel? S'il vous plaît ** éditez votre question ** pour le motiver. –

+0

@BasileStarynkevitch Je souhaite savoir quel programme sera (probablement) exécuté à l'avance à des fins de test. – DevNull

Répondre

3

est-il un moyen simple et direct, pour tester ce que le premier « chemin complet pour exécuter » évaluera à, sans avoir à itérer manuellement tous les éléments dans l'environnement PATH variable $

Non, vous devez parcourir $PATH (c'est-à-dire getenv("PATH") en code C). Certaines bibliothèques (non standard) fournissent un moyen de le faire, mais c'est vraiment si simple que vous ne devriez pas vous embêter. Vous pouvez utiliser strchr(3) pour trouver la "prochaine" occurrence du colon :, codant ainsi cette boucle est vraiment simple. Comme Jonathan Leffler commenté, ils sont des subtilités (par exemple des autorisations, des liens symboliques suspendus, certains autres processus ajoutant un nouvel exécutable à un répertoire mentionné dans votre $PATH) mais la plupart des programmes les ignorent.

Et ce qui est vraiment pertinent est la valeur PATH avant d'exécuter execvp.En pratique, il s'agit de la valeur PATH au démarrage de votre programme (car les processus externes ne peuvent pas le modifier). Vous avez juste besoin d'être sûr que votre programme ne change pas PATH ce qui est très probable (le cas de coin, et difficile, serait un autre thread du même process - en changeant la variable d'environnement PATH avec putenv(3) ou setenv(3)).

Dans la pratique le PATH ne changera pas (à moins que vous avez un changement de code explicitement). Même si vous utilisez des bibliothèques propriétaires et que vous n'avez pas le temps de vérifier leur code source, vous pouvez vous attendre à ce que PATH reste le même pendant l'exécution de votre processus. Si vous avez besoin de quelque chose de plus précis, et en supposant que vous utilisez execp fonctions sur les noms de programmes qui sont des constantes de temps de compilation, ou au moins constante après l'initialisation de votre programme, vous pouvez faire ce que beaucoup de shells font: mise en cache "le résultat de la recherche du PATH dans une table de hachage, et en utilisant execve sur cela. Encore, vous ne pouvez pas éviter le problème de certains autre processus en ajoutant ou en supprimant des fichiers dans les répertoires mentionnés dans votre PATH; mais la plupart des programmes s'en fichent (et sont écrits avec l'hypothèse implicite que cela n'arrive pas, ou est notifié à votre programme: regardez le rehash intégré de zsh comme exemple).

Mais vous toujours besoin de tester contre l'échec de exec (y compris execlp(3) & execve(2)) et fork fonctions. Ils peuvent échouer pour plusieurs raisons, même si le PATH n'a pas changé et que les répertoires et les fichiers qui y sont mentionnés n'ont pas été modifiés.

+0

Il est difficile d'analyser une valeur PATH. Formellement, si le premier caractère est un signe deux-points, ou si le dernier caractère est un signe deux-points, ou s'il y a deux deux-points adjacents dans le PATH, alors le nom du répertoire est (implicitement) ''. '' (Point, le répertoire courant). Il y a aussi d'autres facteurs compliqués: vérifier les permissions sur le fichier, les listes de contrôle d'accès (qui peuvent cacher qu'un utilisateur ou un groupe a l'autorisation), peut-être vérifier les permissions du répertoire, mais si vous pouvez vérifier les permissions sur le fichier, vous êtes habituellement OK. –

+0

@JonathanLeffler: en principe, vous avez parfaitement raison. En pratique, on s'en fiche souvent. –

+0

Merci. Ceci est beaucoup plus instructif que le "duplicata possible" lié à cette question. – DevNull