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


22

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

POSIXは、たとえば、標準psが存在することを保証していますか、/bin/psまたはPATH環境変数を取得した値にリセットしてから、PATH confstr(_CS_PATH, pathbuf, n);検索でユーティリティを実行する必要がありますか?


私は彼らの間で、コマンドの数のため、POSIXが言うことを私の頭の後ろに持っている(1)編(のために重要であるmksh、という、)場合、彼らが利用可能な、彼らはまたしなければならない到達下に/binすなわち、/bin/ed使用可能でなければなりませんedがインストールされている場合。私は今それを見つけることができませんが、LSBがそれに依存していることを知っています、そしてそれを理論的根拠として使用してバグレポートを成功裏に守ったので、少なくともある時点で真実だったに違いありません。(または、POSuX以外のものであり、私は覚えていませんが、残りは真実です。)
mirabilos

回答:


33

いいえ、主にシステムがデフォルトで準拠すること、またはPOSIX標準のみに準拠することを必要としないという理由で(他の標準を除外して)、そうではありません。

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

shあることが保証されていません/bin。Solarisでは、/bin/shSolaris 10まではBourneシェル(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システムなどの一部のシステムでは、POSIXLY_CORRECTコンプライアンスを確保するために変数を設定するなどの手順が必要になることに注意してください)。

次のようなことも試してください:

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

shinが$PATHあり、それがBourneのようであり、aがgetconfあり、それがあなたが興味を持っているPOSIXのバージョンのものであることを期待して。


#!で何をしますか?
ジョシュア

13
@ジョシュア:あなたが/usr/bin/env存在し、主にPOSIXに準拠していることを祈ります。
ケビン

3
@Kevinまたはあなたは、古ユニックスの癖に慣れ、#を調整します!正しいパスを使用する行。
cas

3
@Kevin:いいえ。/usr/bin/envは、(実際には)よりも移植性の低いハックです/bin/sh。POSIXごと、シェルスクリプトを書くためのポータブルな方法はありません何で#!すべてで。ファイルは実行可能だがENOEXEC(有効なバイナリでexecvpはない)、標準シェルを介して実行することです。:-)もちろん実際にはこれは悪い考えであり、あなたはただ使うべき#!/bin/shです。
R ..

2
@GeoffNixon、あなたが参照している部分は、_POSIX_C_SOURCEを使用しない、使用できない、または使用したくない場合の代替手段です。$PATHCではなくシェルからの設定を行います。
StéphaneChazelas

3

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

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

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

確かに、標準でこれを行うための唯一の標準的な指定方法は、経由(Cで)あるunistd.hの_CS_PATH、またはシェルで、の組み合わせを介しcommandgetconfユーティリティ、すなわち、PATH="$(command -p getconf PATH)" command -v ps常に独特の絶対パスを返す必要がありますPOSIX準拠の特定のシステムで提供されます。それは実装定義であるが、それは、されたシステムのデフォルトのパス変数に含まれている経路、これらUtilitesをは常に必要があり、その中に指定されたパスのいずれかで、利用可能なユニークな、そして準拠します。ps

参照:< unistd.h >、コマンド


しかし、shには、鶏と卵の問題があります。これPATH=$(command -p getconf PATH)は、POSIX環境のPOSIXシェルからのみ機能します。POSIXは、その環境に入る方法を指定せず、文書化するだけです。たとえば、Solarisでは、標準の2つの異なるバージョンに対して異なる値を返すa /usr/xpg4/bin/getconfとa があり、デフォルト値のにも、a もありません。IIRCがXPG4に準拠しているものがあります。/usr/xpg6/bin/getconf_CS_PATH/usr/xpg4/bin/usr/xpg6/bin$PATH/usr/bin/getconf
ステファンシャゼラス

Solaris 11+(UNIX 03+認定)バージョンでも同様ですか?私は常に `` `アプリケーション...を読みました。getconfPATHによって返されたPATHの問い合わせによって決定されるべきです。返されたパス名がシェル組み込みではなく絶対パス名であること確認してください。たとえば、標準のshユーティリティの場所を特定するには、次のコマンドを使用します。command -v sh一部の実装では、これが返される場合があります。/ usr / xpg4 / bin / sh `` `これはsh、デフォルトのシェルからPOSIX 。
ジェフニクソン

1
POSIXには、特定のシステムのgetconfデフォルト$PATHにコマンドがあるべきだということは何もありません。たとえば、POSIX環境を取得するには、エミュレーションレイヤーを起動する必要があります。エミュレーションレイヤーがなければ、Unixのようなコマンドはまったく実行されません(たとえばWindowsを考えてください)。一度準拠環境にgetconf PATH なれば、$PATH準拠ユーティリティにアクセスできるようになりますが、POSIX環境にいた場合は、おそらく既にそうでした。getconf psが返される場合があることに注意してくださいps。持つps組み込みことは許可されています。
ステファンシャゼラス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.