Desde C, ¿cuál es la forma más fácil de ejecutar una utilidad estándar (por ejemplo, ps) y ninguna otra?
¿Garantiza POSIX que, por ejemplo, un estándar ps
se encuentra en /bin/ps
o debería restablecer la variable de entorno PATH para lo que me pasa con confstr(_CS_PATH, pathbuf, n);
y vuelva a ejecutar la utilidad de ruta de búsqueda?
/bin
, es decir,/bin/ed
deben ser utilizables si ed está instalado No puedo encontrarlo en este momento, pero sé que LSB depende de ello, y he defendido con éxito los informes de errores utilizando eso como justificación, por lo que al menos debe haber sido cierto en algún momento. (O era algo más que POSuX y lo recuerdo mal, pero el resto es cierto.)Respuestas:
No, no lo hace, principalmente por el hecho de que no requiere que los sistemas se ajusten de manera predeterminada o que cumplan solo con el estándar POSIX (con la exclusión de cualquier otro estándar).
Por ejemplo, Solaris (un sistema certificado compatible) eligió la compatibilidad con versiones anteriores para sus utilidades
/bin
, lo que explica por qué se comportan de manera arcana y proporciona utilidades compatibles con POSIX en ubicaciones separadas (/usr/xpg4/bin
,/usr/xpg6/bin
... para diferentes versiones de XPG (ahora fusionadas en POSIX), que en realidad son parte de componentes opcionales en Solaris).Incluso
sh
no se garantiza que esté en/bin
. En Solaris,/bin/sh
solía ser el shell Bourne (por lo que no es compatible con POSIX) hasta Solaris 10, mientras que ahora es ksh93 en Solaris 11 (todavía no es totalmente compatible con POSIX, pero en la práctica es más que eso/usr/xpg4/bin/sh
).Desde C, puede usar
exec*p()
y asumir que está en un entorno POSIX (en particular con respecto a laPATH
variable de entorno).También puede establecer la
PATH
variable de entornoO puede determinar en el momento de la compilación la ruta de las utilidades POSIX que desea ejecutar (teniendo en cuenta que en algunos sistemas como los GNU, necesita más pasos, como establecer una
POSIXLY_CORRECT
variable para garantizar el cumplimiento).También puedes probar cosas como:
Con la esperanza de que hay una
sh
en$PATH
, que es similar a Bourne, que también hay unagetconf
y que es el de la versión de POSIX Múdese interesados.fuente
/usr/bin/env
exista y cumpla principalmente con POSIX./usr/bin/env
es un truco aún menos portátil (en la práctica) que/bin/sh
. Según POSIX, la forma portátil de escribir un script de shell es sin ningún tipo#!
de . Si un archivo es ejecutable peroENOEXEC
(no es un binario válido),execvp
es ejecutarlo a través del shell estándar. :-) Por supuesto, en la práctica esta es una mala idea y solo debes usarla#!/bin/sh
.$PATH
desde el caparazón en lugar de desde C.En realidad, respondería en gran medida que sí . POSIX garantiza:
Aunque no se garantiza necesariamente que cada utilidad esté en un directorio particular en todos los sistemas (
/bin/ps
), siempre se garantiza que se pueda encontrar en la RUTA predeterminada del sistema, como un archivo ejecutable.De hecho, la única forma especificada por el estándar para hacer esto en el estándar es (en C) a través
unistd.h
de _CS_PATH, o en el shell, a través de una combinación decommand
ygetconf
utilidades, es decir,PATH="$(command -p getconf PATH)" command -v ps
siempre debe devolver la ruta absoluta única de los que cumplen con POSIXps
suministrado en un sistema particular. Es decir, si bien es definido por la implementación , que los caminos están incluidos en la variable PATH por defecto del sistema, estas utilidades debe siempre estar disponible, único y compatible, en una de las rutas especificadas en el mismo.Ver: < unistd.h >, comando .
fuente
PATH=$(command -p getconf PATH)
solo funcionará desde un shell POSIX en un entorno POSIX. POSIX no especifica cómo ingresa a ese entorno, solo que esté documentado. Por ejemplo, en Solaris, tiene un/usr/xpg4/bin/getconf
y un/usr/xpg6/bin/getconf
que devolvería valores diferentes_CS_PATH
para las dos versiones diferentes del estándar y ninguno/usr/xpg4/bin
ni/usr/xpg6/bin
está en el valor predeterminado de$PATH
. Hay un/usr/bin/getconf
IIRC que le da conformidad con XPG4.sh
desde cualquier shell predeterminado .getconf
comando en el valor predeterminado$PATH
de un sistema determinado. Por ejemplo, obtener un entorno POSIX puede implicar iniciar una capa de emulación, sin la cual no ejecutaría ningún comando similar a Unix (piense en Windows, por ejemplo). Una vez que se encuentre en un entorno compatible,getconf PATH
obtendrá un$PATH
acceso a las utilidades compatibles, pero si estuviera en un entorno POSIX, probablemente ese ya era el caso. Tenga en cuenta quegetconf ps
puede volverps
. Tenerps
incorporado está permitido.