POSIX(ポジックス)は、UNIX系OSのAPIとシェル・コマンドの振る舞いを揃えるための標準規格です。「POSIX準拠」と書かれたOSやライブラリを前にして、何が保証されていて何が保証されていないのかを判断できるよう、本記事では規格の現行版、中身の構成、ヘッダー別のAPI一覧、準拠と認証の違い、手元の環境が対応する版の確かめ方を順に説明します。コマンドとCのコード例は、macOS 26.6.2上で実行した結果をそのまま載せています。
まとめ:POSIXの要点
POSIXは Portable Operating System Interface の略で、IEEE Std 1003.1 として規格化されています。現行版は2024年6月14日に公開された POSIX.1-2024(The Open Group Base Specifications Issue 8)です。
規格が定めるのはアプリケーションから見たインタフェースだけです。open・fork・pthread_create といったC言語の関数、sh の文法、ls や grep などのユーティリティの振る舞いが対象で、カーネルの作りやGUI、パッケージ管理は対象外です。
「POSIX準拠」という言葉は、IEEE と The Open Group のPOSIX認証、POSIXを含むSUSに対するUNIX認証、試験を受けずに規格に沿って実装しているだけの状態、の3つを指しうるため、区別して読む必要があります。2026年9月時点のUNIX認証の登録一覧に載っているのは macOS 26 Tahoe、AIX、HP-UX などで、主要なLinuxディストリビューションは載っていません。それでもLinuxはglibcを通じて、実用上POSIXのAPIの大半を備えています。
移植性が必要なコードでは、POSIXの範囲で書き、Linux固有のepollやbash固有の文法は必要な箇所に閉じ込めます。この判断の基準を後半で具体的に示します。
POSIXとは|IEEE Std 1003.1が定めるOSインタフェースの標準規格
POSIXはIEEEの商標で、IEEE Std 1003.n と ISO/IEC 9945 の各部からなる規格群を指します。もとは1988年の IEEE Std 1003.1-1988 だけを指す名前でしたが、現在は規格群全体の呼び名です。単に「POSIX」と言った場合は、中核である POSIX.1(IEEE Std 1003.1)を指すのが普通です。
POSIXの読み方と名前の由来
POSIX FAQ(The Open Group)によると、名前はリチャード・ストールマンが提案したもので、発音は「pahz-icks, as in positive, not poh-six」とされています。positive の「pos」と同じ音で、「ポーシックス」とは読まないという意味です。日本語ではコトバンクなどの辞書が「ポジックス」と表記しており、この読み方が一般的です。
POSIX.1-2024に至る版の変遷
POSIX.1はおよそ10年ごとに大きく改訂されてきました。各版の値は、Cのヘッダー <unistd.h> のマクロ _POSIX_VERSION に入ります。この値で手元の環境がどの版を名乗っているかが分かります(確かめ方は後述)。
| 版 | 公開 | 主な内容 | _POSIX_VERSION |
|---|---|---|---|
| IEEE Std 1003.1-1988 | 1988年9月30日 | 最初のPOSIX.1 | 198808L |
| POSIX.1-1990(ISO/IEC 9945-1:1990) | 1990年 | 国際規格として発行 | 199009L |
| IEEE Std 1003.1b-1993 | 1993年 | リアルタイム拡張 | - |
| IEEE Std 1003.1c-1995 | 1995年 | スレッド(pthreads) | - |
| POSIX.1-2001 | 2001年 | SUSと統合 | 200112L |
| POSIX.1-2008 / 2017 | 2008年 / 2018年 | 2017年版は正誤反映 | 200809L |
| POSIX.1-2024(Issue 8) | 2024年6月14日 | 現行版 | 202405L |
2017年版(The Open Group では Issue 7, 2018 edition として公開)は値が200809Lのまま変わっていません。規格の文書は The Open Group と IEEE、ISO/IEC の3者が共同で保守しています。The Open Group の Single UNIX Specification(SUS)は、この Base Specifications を中核とし、X/Open Curses などを加えた仕様です。SUSとUNIX商標の関係はUnixとは?Linuxとの違い・POSIXと認証UNIXの実際から移行判断まで実装者向けに解説で扱っています。
POSIX.1-2024の中身|4巻の構成と規格の対象外
POSIX.1-2024は pubs.opengroup.org で無償公開されており、次の4巻で構成されています。
| 巻 | 定める内容 | 例 |
|---|---|---|
| Base Definitions | 用語、ヘッダー、環境変数、正規表現 | <unistd.h>、PATH、BRE/ERE |
| System Interfaces | Cから呼ぶ関数 | open、fork、pthread_create |
| Shell and Utilities | shの文法とコマンド | case文、ls、grep、find |
| Rationale | 規定の理由(参考) | 削除・追加の経緯 |
正規表現の BRE(基本正規表現)と ERE(拡張正規表現)、[[:alpha:]] のような文字クラスも Base Definitions で定義されています。grep や sed の記法が言語ごとの正規表現と微妙に違うのはこのためで、方言の比較は正規表現とは?基本記号の読み方と言語ごとの方言・ReDoS対策を実装目線で解説にまとめています。
POSIX.1-2024で追加された関数とコマンド
Issue 8では、各OSが個別に実装して広く使われていた機能が取り込まれました。
- 関数:strlcpy・strlcat(宛先バッファの全体サイズを指定する文字列のコピーと連結)、reallocarray(乗算オーバーフローを検査する再確保)、ppoll、posix_getdents、_Fork、gettext など
- ユーティリティ:readlink、realpath、timeout、gettext、ngettext、msgfmt、xgettext の7個
realpath や timeout はGNU coreutilsでは以前から使えたため、2017年版に準拠した環境のシェルスクリプトでは、これらを使うと移植性が保証されませんでした。2024年版に準拠した環境が揃えば、この2つを移植可能な前提として使えます。ただし、後述のとおり macOS 26.6.2 が返す値は2001年版の200112で、OSの申告値が2024年版に追いつくまでは実装の有無を個別に確かめる必要があります。
POSIXが規定しない範囲
POSIXが揃えるのはソースコードの互換性で、バイナリの互換性ではありません。同じCのコードでも、Linux向けにビルドした実行ファイルはmacOSでは動きません。
次のものも規格の外にあります。
- カーネルの構造:ある関数をシステムコールで実装するか、ライブラリ内で実装するかは実装者の自由です。POSIXは関数の振る舞いだけを定めます。
- GUI、パッケージ管理、サービス管理(systemd や launchd)
- OS固有の高性能なAPI:Linuxの epoll・inotify、macOSとBSDの kqueue
POSIX APIの一覧|ヘッダー別の代表的な関数
System Interfaces巻の関数のうち、実務でよく使うものをヘッダー別に整理すると次のとおりです。
| ヘッダー | 分野 | 代表的な関数・マクロ |
|---|---|---|
| <unistd.h> | プロセス・入出力 | fork、execvp、read、write、close、sysconf |
| <fcntl.h> | ファイルを開く | open、openat、fcntl |
| <sys/stat.h> | 属性・パーミッション | stat、chmod、mkdir、umask |
| <dirent.h> | ディレクトリ | opendir、readdir、posix_getdents |
| <sys/wait.h> | 子プロセスの回収 | waitpid、WIFEXITED |
| <spawn.h> | プロセス生成 | posix_spawn、posix_spawnp |
| <signal.h> | シグナル | sigaction、kill、sigprocmask |
| <pthread.h> | スレッド・排他 | pthread_create、pthread_mutex_lock |
| <sys/socket.h> | ソケット | socket、bind、connect、accept |
| <poll.h> | 多重待ち | poll、ppoll |
| <time.h> | 時刻 | clock_gettime、nanosleep |
| <regex.h> | 正規表現 | regcomp、regexec |
各関数の正確な仕様は、POSIX.1-2024 のSystem Interfaces 巻の関数索引から関数名ごとのページを引くのが確実です。ソケットの使い方はソケットとは?Pythonで作って動かすTCP・UDP・UNIXドメインの実装入門で扱っています。
POSIX APIで子プロセスを起動するCのコード例
fork で子プロセスを作り、execlp で uname を実行し、waitpid で終了コードを受け取る最小の例です。先頭の _POSIX_C_SOURCE は機能テストマクロで、「POSIX.1-2008の範囲の宣言を使う」とコンパイラに伝えます。
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(void) {
printf("_POSIX_VERSION=%ld\n", (long)_POSIX_VERSION);
printf("sysconf(_SC_VERSION)=%ld\n", sysconf(_SC_VERSION));
fflush(stdout);
pid_t pid = fork();
if (pid == -1) { perror("fork"); return 1; }
if (pid == 0) {
execlp("uname", "uname", "-s", (char *)NULL);
perror("execlp");
_exit(127);
}
int status;
if (waitpid(pid, &status, 0) == -1) { perror("waitpid"); return 1; }
if (WIFEXITED(status))
printf("child exit=%d\n", WEXITSTATUS(status));
return 0;
}
macOS 26.6.2 で cc -std=c11 -Wall -Wextra -pedantic を付けてビルドすると警告は出ず、実行結果は次のとおりでした。
_POSIX_VERSION=200112
sysconf(_SC_VERSION)=200112
Darwin
child exit=0
fork の直前の fflush は省略しないでください。出力先がパイプやファイルのとき、printf の内容は親プロセスのバッファに溜まり、終了時まで書き出されません。今回の例で fflush を外してパイプへ出力すると、子の出力した Darwin が最初の行に来て、順序が崩れました。子が exec せずに exit で終わる作りでは、複製されたバッファの内容が二重に出力されることもあります。
POSIX準拠とPOSIX互換の意味|認証製品と実装上の準拠
「POSIX準拠」「POSIX互換」という言葉は、次の意味で使われています。資料を読むときは、どの意味で書かれているかを区別してください。
- POSIX認証:IEEE と The Open Group が運営する「POSIX: Certified by IEEE and The Open Group」の要件を満たした製品。POSIX規格そのものへの適合を示します。
- UNIX認証:The Open Group の Open Brand 制度で、SUS に基づく製品標準(UNIX 03 や UNIX V7)への適合を登録した製品。UNIXの商標を使えるのはこちらで、POSIX認証を受けただけでは名乗れません。
- 準拠を目標に実装:試験は受けていないが、規格に沿って作っている。glibc は公式に「POSIX.1-2008 を含む関連規格に従うことを目標とする」と説明しています。
- 一部互換:主要なAPIやコマンドを備えるが、網羅はしていない。
主要OSのPOSIX対応状況
The Open Group のUNIX認証の登録一覧(2026年9月17日確認)をもとに、主要OSの状況を整理しました。
| OS | UNIX認証 | 実態 |
|---|---|---|
| macOS 26 Tahoe | UNIX 03 登録 | Apple silicon版とIntel版 |
| IBM AIX 7 | UNIX V7 / UNIX 03 | V7登録は7.2 TL5以降 |
| HP-UX 11i V3 | UNIX 03 登録 | B.11.31以降 |
| Linux | 登録なし | glibc等で大半を実装 |
| FreeBSD | 登録なし | 大半を実装 |
| Windows | 登録なし | WSL上のLinuxで利用 |
UNIX V7 の登録は AIX の1件だけです。登録一覧のHTMLには Solaris などの行がコメントとして残っていますが、画面には表示されず、有効な登録ではありません。
Linux と FreeBSD は認証を受けていませんが、サーバーで使うPOSIX APIはほぼ揃っています。違いが出るのは、認証の有無よりもGNU拡張やOS固有APIへの依存です。各OSの詳細はLinuxとは?仕組み・ディストリビューション・サーバー用途を実装目線で解説【2026年版】とFreeBSDとは?Linuxとの違い・ZFS/jail/bhyveの実装から採用判断まで実装者向けに解説を参照してください。
WindowsのPOSIXサブシステムとWSL
Windows NT 4.0 と Windows 2000 には、POSIXアプリケーションを動かすための環境サブシステムがありました。Microsoft のセキュリティ情報 MS04-020 には「Windows XP and Windows Server 2003 do not contain the POSIX subsystem」と書かれています。その後のSubsystem for UNIX-based Applications(SUA)も、Windows Server 2012 で非推奨となり、2012 R2 で削除されました。
現在の選択肢は WSL です。WSL 1 は Linux のシステムコールを Windows 側で変換する方式でしたが、既定の WSL 2 は軽量VMの中で Microsoft が提供する Linux カーネルを動かします。そのため、WSL 2 でPOSIX APIを使う場合、実際に動いているのはLinuxです。WSL以外では、cygwin1.dll がPOSIX APIの多くを提供する Cygwin があり、ソースから再ビルドすればWindowsのネイティブプロセスとして動かせます。構築手順はWSLで開発環境を構築する手順|.wslconfig調整とDocker連携・肥大化の対処にまとめています。
手元の環境が対応するPOSIX版を確かめる方法
OSが名乗っているPOSIXの版は、getconf コマンドで確認できます。
$ getconf _POSIX_VERSION
200112
$ getconf PATH
/usr/bin:/bin:/usr/sbin:/sbin
上は macOS 26.6.2 での実行結果です。SDKの <sys/unistd.h> でも _POSIX_VERSION は 200112L と定義されていました。macOS 26 Tahoe は UNIX 03 に登録されていますが、UNIX 03 は Single UNIX Specification Version 3 に基づく認証なので、2001年版の値を返すことと矛盾しません。つまり「UNIX認証済み=最新のPOSIXに対応」ではありません。
glibc の getconf も _POSIX_VERSION という名前を受け付けます(ソース posix/getconf.c で _SC_VERSION に対応付けられています)。
getconf PATH は、POSIXのユーティリティが揃ったPATHを返します。環境変数PATHが書き換えられた環境でも標準のコマンドを確実に見つけたいとき、スクリプトの冒頭で使えます。環境変数の扱い全般は環境変数とは?Linux・Windowsの設定方法とDocker・CIでの受け渡しで解説しています。
Cのコードで _POSIX_C_SOURCE に 200809L などの値を定義すると、ヘッダーがどの版のPOSIXの機能を公開するかを指定できます。これは公開する宣言を制御する仕組みで、規格外のAPIを使っていないことを検査する機能ではありません(glibcのマニュアルも、厳密な規格適合の確認には使えないと注意しています)。また、値を上げても、OSが実装していない関数が使えるようになるわけではありません。posix_getdents のような2024年版の関数を使う前に、対象OSのmanページで実装の有無を確かめてください。
POSIXの範囲で書くべき場面と書かなくてよい場面
移植性を常に最優先する必要はありません。判断の基準は「そのコードが、動作を確認していない環境で実行されるかどうか」です。
#!/bin/sh のスクリプトで通用するPOSIXの文法の範囲
シバンに #!/bin/sh と書いたスクリプトは、Debian や Ubuntu では dash で、macOS では POSIX モードの bash 3.2 で動きます。bash 固有の [[ ]] を使うと、bash では通っても dash では失敗します。
#!/bin/sh
name="posix"
if [[ $name == p* ]]; then
echo "match"
fi
$ bash bashism.sh
match
$ dash bashism.sh
bashism.sh: 3: [[: not found
$ echo $?
0
注意すべきなのは、dash がエラーを出してもスクリプトの終了コードが0のままになる点です。if の条件が失敗として扱われ、分岐が静かに飛ばされるだけなので、CIのジョブは成功扱いになります。POSIXの範囲では case 文で書きます。
#!/bin/sh
name="posix"
case $name in
p*) echo "match" ;;
esac
この書き方なら dash でも match が出力されました。配列や [[ ]] がどうしても必要なら、シバンを #!/usr/bin/env bash にして、bash を前提にしていることをファイル自体に明記してください。
OS固有APIを使ってよい場面
Linux上のコンテナでしか動かず、同時接続が多いサーバーなら、poll ではなく epoll を第一候補にします。poll は呼び出しのたびに監視対象の全件を配列で渡す設計で、epoll のmanページは epoll を多数のファイルディスクリプタに対応できるAPIとして説明しています。どちらを選ぶかは、想定する接続数で両方を計測して決めます。epoll を呼ぶ処理は共通のインタフェースの裏に閉じ込め、残りのコードはPOSIXの範囲で書いておきます。こうしておけば、macOSの開発機では kqueue による実装を同じインタフェースで用意でき、差し替えの範囲がそこだけに限られます。ただし、エッジトリガーの扱いなど両者の動作の違いは、それぞれの環境でテストして確かめる必要があります。
避けるべきなのは、開発機のmacOSとCIのLinuxで、GNU版とBSD版のコマンドの違いに気づかないまま混在させることです。代表例は sed -i です。GNU版は拡張子の引数を省略できますが、BSD版は sed -i '' のように空文字列を渡す必要があります。POSIX.1-2024 の sed が定めるオプションは -E と -n(ほかに -e・-f)だけで、-i はありません。両方の環境で動かすスクリプトでは、sed 's/a/b/' file > file.tmp && mv file.tmp file のように、一時ファイルへの書き出しが成功したときだけ mv で置き換えます。この方法では新しいファイルが元のファイルと入れ替わるため、パーミッションや所有者、ハードリンク、シンボリックリンク先を保つ必要があるファイルでは、置き換える前にそれらの扱いを確認してください。
よくある質問
POSIXは何と読みますか?
日本語では「ポジックス」と読むのが一般的です。POSIX FAQ(The Open Group)には、英語の発音は positive の「pos」と同じ「pahz-icks」と書かれています。
POSIX標準の現行版はどれですか?
2024年6月14日に公開された POSIX.1-2024(IEEE Std 1003.1-2024、The Open Group Base Specifications Issue 8)です。<unistd.h> の _POSIX_VERSION の値は 202405L です。
LinuxはPOSIX準拠ですか?
The Open Group のUNIX認証の登録一覧には、主要なLinuxディストリビューションは載っていません。一方で、glibc は POSIX.1-2008 を含む関連規格に従うことを目標としており、実用上はPOSIXのAPIの大半を使えます。
WindowsでPOSIXのプログラムは動きますか?
Windows 本体の旧POSIXサブシステムとSUAは提供が終わっています。現在は WSL 2 が軽量VM上で動かすLinuxの上で実行するか、Cygwin を使ってソースから再ビルドする方法があります。
POSIX APIの一覧はどこで確認できますか?
The Open Group が pubs.opengroup.org で公開している POSIX.1-2024 の System Interfaces 巻(関数)と Shell and Utilities 巻(コマンド)に、全件が掲載されています。本記事では、実務でよく使う関数をヘッダー別の表にまとめています。