Was ist in C der einfachste Weg, um ein Standarddienstprogramm (z. B. ps) und kein anderes auszuführen?
Gewährleistet POSIX, dass beispielsweise ein Standard vorhanden ps
ist, /bin/ps
oder sollte ich die Umgebungsvariable PATH auf das zurücksetzen, was ich erhalte, confstr(_CS_PATH, pathbuf, n);
und das Dienstprogramm dann über die PATH-Suche ausführen?
/bin
/bin/ed
Antworten:
Nein, dies ist nicht der Fall, hauptsächlich aus dem Grund, dass für Systeme keine Standardkonformität oder nur die Einhaltung des POSIX-Standards (unter Ausschluss eines anderen Standards) erforderlich ist .
Zum Beispiel Solaris (ein zertifiziertes konformes System) wählte die Abwärtskompatibilität für sein Dienstprogramme
/bin
, was erklärt , warum diejenigen , verhalten sie in obskuren Wegen und POSIX-konformen Dienstprogramme in getrennten Standorten bieten (/usr/xpg4/bin
,/usr/xpg6/bin
... für verschiedene Versionen der XPG (jetzt verschmolzen im POSIX) -Standard, wobei diese Komponenten tatsächlich Teil optionaler Komponenten in Solaris sind.Auch
sh
ist nicht garantiert, in zu sein/bin
. Unter Solaris/bin/sh
früher das Bourne - Shell (also nicht POSIX - konform) bis Solaris 10, während es jetzt ksh93 in Solaris 11 (noch nicht vollständig POSIX - konform, aber in der Praxis mehr als/usr/xpg4/bin/sh
).Ab C können Sie verwenden
exec*p()
und davon ausgehen, dass Sie sich in einer POSIX-Umgebung befinden (insbesondere in Bezug auf diePATH
Umgebungsvariable).Sie können auch die
PATH
Umgebungsvariable festlegenOder Sie können zum Zeitpunkt der Erstellung den Pfad der POSIX-Dienstprogramme bestimmen, die Sie ausführen möchten (unter Berücksichtigung der Tatsache, dass auf einigen Systemen wie GNU weitere Schritte erforderlich sind, z. B. das Festlegen einer
POSIXLY_CORRECT
Variablen, um die Konformität sicherzustellen).Sie können auch Folgendes ausprobieren:
In der Hoffnung, dass es ein
sh
In gibt$PATH
, dass es Bourne-artig ist, dass es auch ein gibtgetconf
und dass es dasjenige für die Version von POSIX ist, an der Sie interessiert sind.quelle
/usr/bin/env
es das gibt und es meistens POSIX-konform ist./usr/bin/env
ist ein noch weniger portabler (in der Praxis) Hack als/bin/sh
. Per POSIX ist die tragbare Art und Weise einen Shell - Skript zu schreiben , ohne#!
überhaupt . Wenn eine Datei aber ausführbar istENOEXEC
(keine gültige Binärdatei),execvp
soll diese über die Standard-Shell ausgeführt werden. :-) Natürlich ist das in der Praxis eine schlechte Idee und du solltest es nur benutzen#!/bin/sh
.$PATH
aus der Muschel anstelle von C.Eigentlich würde ich größtenteils ja antworten . POSIX garantiert:
Obwohl es nicht unbedingt gewährleistet , dass jedes Dienstprogramm über alle Systeme in einem bestimmten Verzeichnis sein soll (
/bin/ps
), ist es immer garantiert der Lage sein , in den Systemstandard PATH gefunden werden, als eine ausführbare Datei.Tatsächlich ist der einzige Standard festgelegten Weg , dies in der Norm zu tun ist (in C) über
unistd.h
‚s _CS_PATH oder in der Schale, über eine Kombination auscommand
undgetconf
Dienstprogramme, alsoPATH="$(command -p getconf PATH)" command -v ps
muss immer den einzigartigen absoluten Pfad der Rückkehr des POSIX-konformps
auf einem bestimmten System geliefert. Das heißt, während die Implementierung festlegt, welche Pfade in der Systemstandardvariablen PATH enthalten sind, müssen diese Utilities in einem der darin angegebenen Pfade immer verfügbar, eindeutig und konform sein.Siehe: < unistd.h >, Befehl .
quelle
PATH=$(command -p getconf PATH)
funktioniert nur von einer POSIX-Shell in einer POSIX-Umgebung. POSIX legt nicht fest, wie Sie in diese Umgebung gelangen, sondern nur, dass dies dokumentiert wird. Unter Solaris haben Sie beispielsweise ein/usr/xpg4/bin/getconf
und ein,/usr/xpg6/bin/getconf
die unterschiedliche Werte für_CS_PATH
die beiden verschiedenen Versionen des Standards zurückgeben und weder den Standardwert von/usr/xpg4/bin
noch/usr/xpg6/bin
den Standardwert von haben$PATH
. Es gibt ein/usr/bin/getconf
IIRC, mit dem Sie XPG4-Konformität erhalten.sh
Standardshell sein .getconf
der Standard$PATH
eines bestimmten Systems einen Befehl enthalten sollte. Zum Abrufen einer POSIX-Umgebung muss möglicherweise eine Emulationsebene gestartet werden, ohne die Sie überhaupt keinen Unix-ähnlichen Befehl ausführen würden (z. B. Windows). Sobald Sie sich in einer kompatiblen Umgebung befinden,getconf PATH
erhalten Sie einen$PATH
Zugang zu kompatiblen Dienstprogrammen. Wenn Sie sich jedoch in einer POSIX-Umgebung befinden, war dies wahrscheinlich bereits der Fall. Beachten Sie, dassgetconf ps
möglicherweise zurückkehrenps
. Mitps
builtin ist erlaubt.