web-dev-qa-db-ja.com

POSIXは標準ユーティリティへのパスを保証しますか?

Cから、標準ユーティリティ(psなど)を実行する最も簡単な方法は何ですか?

POSIXは、たとえば、標準のpsが_/bin/ps_にあることを保証しますか、またはPATH環境変数をconfstr(_CS_PATH, pathbuf, n);で取得したものにリセットしてから、PATHを介してユーティリティを実行しますか? -探す?

22
PSkocik

いいえ、主にシステムがデフォルトでに準拠する必要がない、またはonly POSIX標準に準拠する必要がないという理由から、その他の標準)。

たとえば、Solaris(認定準拠システム)は、_/bin_のユーティリティの下位互換性を選択しました。これにより、それらが難解な方法で動作する理由が説明され、POSIX準拠のユーティリティが別の場所に提供されます(_/usr/xpg4/bin_、_/usr/xpg6/bin_...異なるバージョンのXPG(現在はPOSIXに統合されています)標準。これらは実際にはSolarisのオプションコンポーネントの一部です)。

shであっても、_/bin_であるとは限りません。 Solarisでは、_/bin/sh_はSolaris 10までBourne Shell(POSIXに準拠していなかった)でしたが、Solaris 11ではksh93になりました(まだ完全にPOSIXに準拠していませんが、実際には_/usr/xpg4/bin/sh_よりも多くなっています)。 。

Cから、exec*p()を使用して、POSIX環境にいると想定できます(特にPATH環境変数に関して)。

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"...);
_

または、ビルド時に実行するPOSIXユーティリティのパスを決定することもできます(GNU onesのような一部のシステムでは、_POSIXLY_CORRECT_コンプライアンスを確保するための変数)。

次のようなことも試すことができます。

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

_$PATH_にshがあること、それがボーンに似ていること、getconfがあること、および興味のあるPOSIXのバージョン用であることを期待して.

33

実際、私は主にyesと答えます。 POSIXは以下を保証します。

  1. is指定された各ユーティリティの標準準拠バージョンへの絶対パスa
  2. そして、この絶対パスを見つけて、このユーティリティを実行できる必要があります。

各ユーティリティがすべてのシステム(_/bin/ps_)の特定のディレクトリにあることは必ずしも保証されていませんが、システムのデフォルトPATHでができることは常に保証されています実行可能ファイルとして。

実際、標準でこれを行うための唯一の標準指定の方法は、Cで_unistd.h_の_CS_PATHを使用するか、シェルでcommandおよびgetconfユーティリティを組み合わせて使用​​することですつまり、PATH="$(command -p getconf PATH)" command -v psは常に、特定のシステムで提供されるthe POSIX準拠のpsの一意の絶対パスを返す必要があります。つまり、実装で定義されたwhichパスはシステムのデフォルトのPATH変数に含まれていますが、これらのユーティリティ常に必須が利用可能で、一意で、準拠しているその中で指定されたパスの。

参照:< nistd.h >、 command

3
Geoff Nixon