web-dev-qa-db-fra.com

POSIX garantit-il les chemins vers les utilitaires standard?

À partir de C, quelle est la façon la plus simple d'exécuter un utilitaire standard (par exemple, ps) et aucun autre?

POSIX garantit-il, par exemple, qu'un ps standard est dans /bin/ps Ou dois-je réinitialiser la variable d'environnement PATH à ce que j'obtiens avec confstr(_CS_PATH, pathbuf, n); puis exécuter l'utilitaire via PATH-recherche?

22
PSkocik

Non, ce n'est pas le cas, principalement parce qu'il n'exige pas que les systèmes soient conformes par défaut, ou conformes niquement au standard POSIX (à l'exclusion de toute autre norme).

Par exemple, Solaris (un système conforme certifié) a choisi la compatibilité descendante pour ses utilitaires dans _/bin_, ce qui explique pourquoi ceux-ci se comportent de manière obscure et fournissent des utilitaires conformes POSIX dans des emplacements distincts (_/usr/xpg4/bin_, _/usr/xpg6/bin_... pour différentes versions du standard XPG (maintenant fusionné en POSIX), celles-ci faisant en fait partie des composants optionnels de Solaris).

Même sh n'est pas garanti d'être dans _/bin_. Sous Solaris, _/bin/sh_ était le Bourne Shell (donc pas compatible POSIX) jusqu'à Solaris 10, alors qu'il est maintenant ksh93 dans Solaris 11 (toujours pas entièrement compatible POSIX, mais en pratique plus que _/usr/xpg4/bin/sh_) .

Depuis C, vous pouvez utiliser exec*p() et supposer que vous êtes dans un environnement POSIX (en particulier en ce qui concerne la variable d'environnement PATH).

Vous pouvez également définir la variable d'environnement PATH

_#define _POSIX_C_SOURCE=200809L /* before any #include */
...
confstr(_CS_PATH, buf, sizeof(buf)); /* maybe append the original
                                      * PATH if need be */
setenv("PATH", buf, 1);
exec*p("ps"...);
_

Ou vous pouvez déterminer au moment de la construction le chemin des utilitaires POSIX que vous souhaitez exécuter (en gardant à l'esprit que sur certains systèmes comme GNU ceux, vous avez besoin de plus d'étapes comme définir un _POSIXLY_CORRECT_ variable pour assurer la conformité).

Vous pouvez également essayer des choses comme:

_execlp("sh", "sh", "-c", "PATH=`getconf PATH`${PATH+:$PATH};export PATH;"
                         "unset IFS;shift \"$1\";"
                         "exec ${1+\"$@\"}", "2", "1", "ps", "-A"...);
_

Dans l'espoir qu'il y a un sh dans _$PATH_, qu'il ressemble à Bourne, qu'il y a aussi un getconf et que c'est celui de la version de POSIX qui vous intéresse dans.

33
Stéphane Chazelas

En fait, je répondrais largement oui. POSIX garantit:

  1. Qu'il y ait un chemin absolu vers une version conforme aux normes de chaque utilitaire spécifié,
  2. Et, que vous devez être capable de trouver ce chemin absolu et pouvoir exécuter cet utilitaire.

Bien qu'il ne soit pas nécessairement garanti que chaque utilitaire soit dans un répertoire particulier sur tous les systèmes (/bin/ps), Il a toujours garanti pour pouvoir se trouver dans le PATH par défaut du système , en tant que fichier exécutable.

En effet, la seule manière standard spécifiée de le faire dans la norme est (en C) via le _CS_PATH de unistd.h, Ou dans le Shell, via une combinaison de command et getconf les utilitaires, c'est-à-dire PATH="$(command -p getconf PATH)" command -v ps doivent toujours renvoyer le chemin absolu unique de le conforme POSIX ps fourni sur un système particulier. Autrement dit, bien qu'il soit défini par l'implémentation qui les chemins sont inclus dans la variable PATH par défaut du système, ces utilitaires doivent toujours être disponible, unique et conforme, dans l'un des chemins qui y sont spécifiés.

Voir: < nistd.h >, command .

3
Geoff Nixon