À partir de C, quelle est la façon la plus simple d'exécuter un utilitaire standard (par exemple, ps) et aucun autre?
Est-ce que POSIX garantit que, par exemple, une norme ps
est dans /bin/ps
ou dois-je réinitialiser la variable d'environnement PATH avec ce que j'obtiens confstr(_CS_PATH, pathbuf, n);
, puis exécuter l'utilitaire via PATH-search?
/bin
, c'est-à-dire qu'elles/bin/ed
doivent être utilisables si ed est installé. Je ne le trouve pas pour le moment, mais je sais que LSB en dépend, et j'ai réussi à défendre les rapports de bogues en utilisant cela comme justification, donc cela doit au moins être vrai à un moment donné. (Ou c'était autre chose que POSuX et je me souviens mal, mais le reste est vrai.)Réponses:
Non, ce n'est pas le cas, principalement parce qu'il n'exige pas que les systèmes soient conformes par défaut , ou uniquement à la norme 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 mystérieuse, et fournissent des utilitaires conformes POSIX dans des emplacements distincts (/usr/xpg4/bin
,/usr/xpg6/bin
... pour différentes versions de XPG (maintenant fusionnées) en POSIX) standard, ceux-ci faisant en fait partie des composants optionnels de Solaris).Même
sh
n'est pas garanti d'être en/bin
. Sous Solaris,/bin/sh
était le shell Bourne (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
).De C, vous pouvez utiliser
exec*p()
et supposer que vous êtes dans un environnement POSIX (en particulier en ce qui concerne laPATH
variable d'environnement).Vous pouvez également définir la
PATH
variable d'environnementOu 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, vous avez besoin de plus d'étapes comme définir un
POSIXLY_CORRECT
variable pour garantir la conformité).Vous pouvez également essayer des choses comme:
Dans l'espoir qu'il y ait un
sh
in$PATH
, qu'il ressemble à Bourne, qu'il y en ait aussi ungetconf
et que c'est celui de la version de POSIX qui vous intéresse.la source
/usr/bin/env
existe et qu'il soit principalement conforme à POSIX./usr/bin/env
C'est un hack encore moins portable (en pratique) que/bin/sh
. Par Posix, la façon portable pour écrire un script shell est sans#!
du tout . Si un fichier est exécutable maisENOEXEC
(pas un binaire valide),execvp
c'est de l'exécuter via le shell standard. :-) Bien sûr, dans la pratique, c'est une mauvaise idée et vous devez simplement l'utiliser#!/bin/sh
.$PATH
la coquille au lieu de C.En fait, je répondrais largement oui . POSIX garantit:
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 est toujours garanti de pouvoir être trouvé dans le PATH par défaut du système, en tant que fichier exécutable.En effet, la seule façon spécifiée par la norme de le faire dans la norme est (en C) via
unistd.h
_CS_PATH de, ou dans le shell, via une combinaison decommand
et desgetconf
utilitaires, c'est-à-dire,PATH="$(command -p getconf PATH)" command -v ps
doit toujours renvoyer le chemin absolu unique de la conformité POSIXps
fourni sur un système particulier. Autrement dit, bien qu'il soit défini par l'implémentation quels chemins sont inclus dans la variable PATH par défaut du système, ces utilitaires doivent toujours être disponibles, uniques et conformes, dans l'un des chemins qui y sont spécifiés.Voir: < unistd.h >, commande .
la source
PATH=$(command -p getconf PATH)
ne fonctionnera qu'à partir d'un shell POSIX dans un environnement POSIX. POSIX ne spécifie pas comment vous entrez dans cet environnement, mais simplement qu'il soit documenté. Par exemple, sur Solaris, vous avez un/usr/xpg4/bin/getconf
et un/usr/xpg6/bin/getconf
qui renverraient des valeurs différentes_CS_PATH
pour les deux versions différentes de la norme et ni l'un/usr/xpg4/bin
ni l' autre ne/usr/xpg6/bin
sont dans la valeur par défaut de$PATH
. Il y en a un/usr/bin/getconf
qui IIRC vous donne la conformité XPG4.sh
partir de n'importe quel shell par défaut .getconf
commande par défaut$PATH
d'un système donné. Par exemple, obtenir un environnement POSIX peut impliquer le démarrage d'une couche d'émulation, sans laquelle vous n'exécuteriez aucune commande de type Unix (pensez à Windows par exemple). Une fois que vous êtes dans un environnement conforme,getconf PATH
vous obtiendrez un$PATH
accès à des utilitaires conformes, mais si vous étiez dans un environnement POSIX, c'était probablement déjà le cas. Notez que celagetconf ps
peut revenirps
. Avoirps
intégré est autorisé.