159
157

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

祝🎉 POSIX.1-2024 (Issue 8) 改定16幎ぶりの倧幅改定でシェルスクリプトはどう新しくなるのか

Last updated at Posted at 2024-06-14

はじめに

自称日本䞀の「POSIX おじさんシェルスクリプト限定」が最新の POSIX 準拠シェルスクリプトの䞖界をご案内いたしたす。POSIX の倧幅な改定である POSIX.1-2024 (IEEE 1003.1-2024, Issue 8) は、2024幎3月21日に The Open Group によっお承認され、5月21日に IEEE で承認され、6月14日に改定されたした。そうです。぀い先皋䞀時間ほど前です。最速で最新情報をお届けいたしおおりたす。前回の倧幅な改定が POSIX.1-2008 なので実に 16 幎ぶりの倧幅改定ですPOSIX.1-2017は小芏暡な修正。なお ISO/IEC での投祚の締め切りは6月28日なので ISO/IEC の承認はただですが、承認されおないず蚀っおも手続き䞊の郜合によるもので、POSIX ず呌ばれおいる暙準芏栌は 3 ぀の暙準化団䜓The Open Group、IEEE、ISO/IECが同じ暙準芏栌を採甚するこずになっおるので内容に関しお異議が出るこずはないはずです。

今回の改定では暙準芏栌の間違い曖昧な点の修正のほか、これたで bashism ず蚀われおいたシェルの拡匵機胜や、GNU コマンドや BSD ç³» Unix の独自コマンドや拡匵されたオプションなどが远加・暙準化され、わずかながら倉曎になった機胜や廃止された機胜もありたす。ちたたにある POSIX 準拠シェルスクリプトの情報のいく぀かは叀くなっおしたいたした。この蚘事では今回の改定でシェルやコマンドがどう倉わるのかに぀いお解説したす。重芁な点はおおむね曞いおいるず思いたすが、挏れがあったら埌で远加したす。たた「将来の方向性」ずしお今回の改定には含たれおいないが将来倉曎するかもしれない情報ず、新しく暙準化された機胜にただ察応しおいない実装のための「回避策」もいく぀か解説しおいたす。

「将来の方向性」(FUTURE DIRECTIONS) は将来のPOSIXで暙準化されるず決たったこずではありたせん。POSIX がそのようにしたいず考えおいるこずであり、実珟するかどうかは OS の実装者が同意しおその内容に察応するこずが前提です。

POSIX.1-2024 の改定では POSIX が参照する C 蚀語が C99 から C17 に倉曎になりたした。ただし本蚘事には C 蚀語に぀いおの話はありたせん。だっお C 蚀語に詳しい人なら䜕人もいるでしょう 私が倪刀打ちできる䞖界ではないので他の人に任せたす。ずは蚀うもののそれだけではちょっず寂しいので、新しく远加・削陀された関数ぞのリンクだけ玹介する予定です。

新しく远加・削陀された POSIX むンタヌフェヌス

POSIX から削陀されたむンタヌフェヌスは、POSIXが「実装しおはいけない」「実装から削陀しろ」ず呜什しおいるわけではなく、「移怍性がない」から䜿甚する堎合は泚意が必芁ずいう意味です。珟実の実装は「拡匵機胜」ずしおこれからも実装しお構いたせんし、移怍性に泚意するのであれば䜿甚しおも構いたせん。それは「拡匵機胜を䜿甚する POSIX 準拠アプリケヌション」ず呌ばれたす。

POSIX が改定されたず蚀っおも埌方互換性を砎壊するような倉曎が芁求されおいるわけではないので安心しおください。ただしここには重倧な事実がありたす。それは今珟圚、各 OS 間で互換性がない動䜜が POSIX の改定で同じ動䜜に統䞀されるものもないずいうこずです。なぜならどの OS でも同じ動䜜に統䞀するずいうこずは、どこかの OS では動䜜を倉曎せねばならず、埌方互換性が砎壊されおしたうからです。安心しおください。POSIX がどれだけ改定されようが、埌方互換性を保぀ために移怍性異なる OS 間の互換性は犠牲になっおおり、移怍性がない郚分はこれからもずっず移怍性はないたたなので、別のシステムに乗り換えるずきは泚意が必芁ですが、今たで䜜ったシェルスクリプトは OS 開発者が埌方互換性を保ずうずする限り、同じ OS ずその埌継バヌゞョンでなら同じように動䜜するはずです。

この蚘事の修正履歎倧きなもののみ

  • 2024-06-23: dash で $'...' に察応する修正が行われおいるこずを远蚘
  • 2024-06-29: compress / uncompress / zcat コマンドに぀いお加筆
  • 2024-06-30: bash で cd コマンドに空文字を指定したずきの挙動に぀いお远蚘
  • 2024-06-30: 「発明をしない」の意味に぀いお補足

あなたは誰

たたには自己玹介ず蚀うか、私がプラむベヌトでやっおいるこずの玹介をしたいず思いたす。宣䌝なので興味がない方はお先ぞどうぞ。

私はシェルスクリプトの䜜成を楜にするためのラむブラリやツヌルを開発しおいたす。もっずも有名な代衚䜜は ShellSpec です。最近 GitHub のスタヌが 1K を超え、ChatGPT さんが 100 回に 1 回ぐらいの確率で私のこずを認知しおくれるようになりたした。どこかの Unix/Linux の準公匏パッケヌゞにも含たれおいるずかいないずか誰かが勝手にやっおるのでリアルに把握しおない。ShellSpec はシェルスクリプト甚の高機胜なテストフレヌムワヌクで、bash だけではなくすべおの POSIX シェルずそれが動く環境に察応しおいるのが特城です。どの環境でも動くようにするために、わずかな POSIX コマンドだけに䟝存し、ほがすべおをシェルスクリプトの蚀語シェル蚀語で実装し、環境䟝存をなくすための高床なシェルプログラミング技術が䜿われおいたす。しばらく開発を停止しおいたのですがただ本調子ではありたせんが再始動したした。最近の修正では AIX 7.2 / 7.3 䞊の bash ず ksh93 ぞの察応が行われおいたす/bin/sh = ksh88f ぞの察応は ksh88f のバグの圱響範囲が倧きく保留䞭。Solaris 10 の ksh88i では動䜜するが ksh88 は基本的に POSIX 準拠ではない。POSIX に完党に準拠しおない叀すぎる ksh88f が悪い。圓然ながら ShellSpec は䞀郚の環境を陀いおCI による継続的なテストが行われおいたす。

シェルスクリプトの倧きな問題点の䞀぀は移怍性の䜎さです。これは䞀般的なシェルスクリプトが環境䟝存のコマンド、すなわち Unix/Linux に暙準で含たれおいる OS 暙準コマンドPOSIX コマンドを含むに倧きく䟝存しおいるのが原因です。䞀般的に実装の数が倚ければ倚いほど実装間の互換性は䜎くなりたす。OS暙準コマンドは耇数の Unix ベンダヌや団䜓がそれぞれ同じようなコマンドを独立しお䜜っおいるのだから互換性が䜎くなるのは圓たり前ず蚀えたす。POSIX は互換性問題を解決しようずする団䜓ではなく、りェブの暙準芏栌を䜜っおいる WHATWG ずは党く方針が違う暙準化団䜓です。このような珟状で「どの環境でも動くシェルスクリプト」を開発するのは至難の業で誰でも簡単にできるようなこずではありたせん。どの環境でも動くシェルスクリプト甚のテストフレヌムワヌクがShellSpec 誕生以前はなかったこずも、移怍性が高いシェルスクリプトを開発するのが難しかった理由の䞀぀でしょう。ShellSpec ではテストに独自の DSL シェルスクリプト互換を䜿甚したすが、DSL を䜿甚しおいる限りはテストコヌドに移怍性があり単䞀のテストコヌドで党おのシェルのテストを行うこずが可胜です。

ShellSpec は Linux、macOS、BSD ç³» Unix、System V ç³» UnixSolaris ず AIX、Windows (WSL 䞊の Linux だけではなくCygwin や BusyBox などを含む など、どの環境でも動きたす。どの環境でも動くずいうのは、どの OS でも動くずいう意味だけではなく、䞖界䞭どの堎所でも動くずいうこずです。最近行った AIX 察応の内容の䞀぀は AIX 環境の time コマンドが原因で発生しおいたロケヌル䟝存をなくすための修正で、C ロケヌルに倉曎するのではなく珟圚のロケヌルを尊重しおどのロケヌル環境でも動くように修正しおいたす。この修正で ShellSpec が察応する環境は曎に増えたしたが、この䟋からもわかるように環境ごずにコマンドの動䜜が違うためどの環境でも動くシェルスクリプトを曞くのは難しいのです。すべおの環境の動䜜を把握しおそれにあらかじめ察応しお曞ける人はたずいたせん。問題は埌から芋぀かりたす。埌から修正をする必芁がありたす。そしたら党おの再テストが必芁です。

人はだれでもミスをしたす。最初から完璧に正しく動くコヌドを曞けるこずはありたせん。シェルスクリプトが環境に䟝存する存圚である以䞊、環境䟝存の問題を完璧に把握しおいる人以倖は必ずバグを含めおしたいたす。それに察凊するには倚数の環境ごずにテストを行うしかありたせん。あなたは最初から完璧なコヌドを曞ける たずえそうだずしおも普通は䞀人で開発するわけではないので、あなただけができおも意味はありたせん。経隓の浅い人が完璧なコヌドを曞けたずしたら驚くべきこずです。そうです。テストは必ず必芁なのです。そしおそのテストは自動化する必芁がありたす。もしテスト自動化の仕組みがなければ手䜜業でテストを行い目芖で結果を確認するしかなくなっおしたいたす。これの䜕が悪いのかは蚀うたでもありたせんよね 環境毎に行う手䜜業で目芖によるテストは時間がかかりミスも発生したす。どのようなテストをしたのずいう蚘録がなく、テスト䜜業を問題なく行ったのかわからず、修正したずきに党䜓を再テストするのが䞍可胜だからです。そのようなテストのやり方が蚱されたのは 2030 幎前たでです。シェルスクリプトは䜜業を自動化するために䜜るものだず蚀うのに、そのシェルスクリプトのテストを手䜜業に頌るようでは皮肉以倖の䜕物でもありたせん。

念の為ですがどのようなシェルスクリプトでもテストをしろずいう話ではありたせん。䜿い捚おで間違うこずがないような数行皋床の小さなシェルスクリプトであればテストは䞍芁です。テストが必芁なのは倚数のシェルスクリプトの組み合わせで動く倧きくお耇雑なシステムや高い信頌性や移怍性が必芁なものだけです。だから倧抵の人には必芁ありたせん。しかしそれでも必芁な堎合もありたす。テストがなければ他の環境で動くか調べるこずができたせんし、安心しお OS のバヌゞョンをアップデヌトするこずもできなくなっおしたいたす。POSIX に準拠しお曞いおいれば「きっず動くかもしれたせん」ではなく、動くずいう保蚌が必芁なのです。環境を倉えたりコヌドを修正したずきに問題なく動くずいう保蚌ができなければ、長く䜿えるシェルスクリプトにはなりたせん。

難しいずはいえ ShellSpec の実珟によりどの環境でも動くシェルスクリプトを䜜るこずが可胜であるこずは蚌明されたした。私がやっおいる掻動はシェルスクリプトの環境䟝存の問題をなくしお、普通にシェルスクリプトを曞くだけで、どの環境でも動くシェルスクリプトを簡単に䜜れるような基盀を䜜るこずです。POSIX に準拠しおシェルスクリプトを曞くずいうのはずおも非効率な䜜業です。POSIX に準拠する䜜業はシェルスクリプトを曞く䞊での本圓の目的ではありたせんし、移怍性を高めたずしおも他の環境に移怍するこず自䜓がほずんどなくなっおしたった珟代では移怍性に力をそそいでもその努力は報われたせん。しかしながら私は OS には倚様性があるべきだず考えおいるので Linux 以倖の BSD ç³» Unix や System V ç³» Unix を無芖したくはありたせん。POSIX 準拠や移怍性の実珟ずいう努力をせずずも「勝手に POSIX に準拠しお高い移怍性が実珟されおいる」ようにするのが最終目暙です。他の蚀語では䜕幎も前から実珟できおいるこずなので、この点でシェルスクリプトは倧きく遅れおいたす。もちろん目暙は移怍性の実珟だけではなく、バグのないシェルスクリプトを誰でも簡単に曞けるようにするこずも目暙の䞀぀です。「その曞き方には問題があるんだぜ」ずいう無駄知識バッドノりハりをひけらかしたりありがたがるのではなく、なくしおしたうのが目暙です。ずは蚀えそのような䞖界をすぐに䜜るこずはできないのでこのような蚘事を曞いお最新情報を広めおいたす。

その他のシェルスクリプトに関する私の研究の成果はこちらで公開しおいたす。すべお改定前のPOSIX で暙準化されおいるシェルずコマンドの機胜のみを䜿っお実装しおいたす。これらを䜿えばシェルスクリプトを曞くのは幟分楜になるでしょう。

  • https://github.com/ko1nksm-shlab
    • sh-string - 文字列操䜜ラむブラリ眮換や trim 凊理など
    • sh-path - パス名操䜜ラむブラリ拡匵子の陀去やパスの正芏化など
    • sh-datetime - 日付ラむブラリUNIX時間ずの倉換や曜日の取埗
    • seq.awk - awk による seq コマンド盞圓機胜の実装
    • sh-maketemp - 䞀時ファむルやディレクトリ䜜成ラむブラリ
    • sh-pipestatus - pipefail ず PIPESTATUS 機胜の実装
      • おたけ: SIGPIPE による゚ラヌを無芖するための関数
    • sh-findcmd - which コマンドの盞圓機胜の実装
    • sh-xorshift - Xorshift による疑䌌乱数生成ラむブラリ
    • sh-fnv1 - FNV1ハッシュ倀蚈算ラむブラリ
    • sh-base64 - Base64 ゚ンコヌダヌ・デコヌダヌ
    • sh-hmac-sha1 - HMAC-SHA1 の実装

䞀郚のツヌルは個人のメむンプロゞェクトにおいおいたす。

  • getoptions - シェルスクリプト甚のオプションパヌサヌ
  • shdotenv - シェル甚のdotenv環境倉数の蚭定ツヌル
  • readlinkf - POSIX コマンドのみを䜿った readlink -f の互換実装
  • url - URL ゚ンコヌド・デコヌドを簡単に行うツヌル
  • sh-i18n - 囜際化翻蚳ラむブラリ

前提知識

POSIX などに関する前提知識の話です。興味がない人は飛ばしおください。

POSIX.1-2024の新機胜はすでに䜿えたす

蚘事のタむトルでシェルスクリプトはどう倉わるのかず曞きたしたが環境によっおは䜕幎も前から新しい機胜が䜿えおいたす。なぜ暙準芏栌ができる前から新しい機胜が䜿えおいたのかず蚀うず、POSIX が行っおいる暙準化䜜業ずは、新しい機胜を䜜るこずではなく既存の実装の動䜜を明文化するこずだからです。こちらで「invention」ずいうキヌワヌドで怜玢しおみるずわかりたすが、POSIX では「発明を行わない」こずは共通認識です。぀たり新しい機胜が「発明」されたのではなく、先進的な POSIX シェルである bash や ksh や、GNU コマンドや BSD コマンドなどに実装されおいたいわゆる「拡匵機胜」から移怍性が高く重芁だず思われた機胜が暙準芏栌に組み蟌たれたした。拡匵機胜ずいう蚀葉は少々誀解を招きやすい蚀葉です。POSIX にずっおは暙準化されおいない機胜はすべお拡匵機胜にあたりたすが、䞀郚の機胜は POSIX が誕生するよりも前からシェルやコマンドが持っおいた機胜です。POSIX スレッドなどの䟋倖はありたすが基本的に POSIX は埌からやっおきお移怍性の芳点から暙準化すべき OS の機胜を遞別しおいるだけであり、シェルやコマンドを含む OS の機胜を䜜るのは、昔から各 Unix/Linux の開発者の圹目です。

POSIX は発明を行わないため、暙準化された機胜ずいうのはすでに䜕幎も前から䜿えた機胜です。したがっお POSIX にこだわっおいない人にずっおはすでに䜿っおる「あの機胜」が暙準化されたずいうだけです。それでは POSIX.1-2024 の改定にはどういう意味があるのでしょうか それは、私のような 「POSIX 準拠シェルスクリプトにうるさい人が、アップデヌトしなければいけない知識」ずいうだけです。今たで POSIX で芏定されおないから䜿わない䜿えないず蚀っおいた「あの機胜」の䜿甚が暙準芏栌䞊は解犁ずなり、うるさく蚀う必芁がなくなったずいうこずです。䞀般的に今䜿っおいるシステムを叀い OS や互換性のないシステムに移行するこずはないでしょうから、POSIX で暙準化された機胜は、珟圚䜿えるのであれば今埌も安心しお䜿えるはずです。

2024-06-30 補足 「発明を行わない」ずいうのは「新しい機胜」を远加しないずいう意味です。すでに実装されおいる機胜ずほが同じ機胜を暙準化のために少し調敎したりしお、䌌たような新しいむンタヌフェヌスを远加するこずはありたす。たた䜕事にも䟋倖はあるので暙準化の過皋でどうしおも必芁ず刀断された堎合には発明が行われるこずもあるでしょう。

各環境の察応状況は自分で調べるしかありたせん

POSIX が改定され新しい機胜が䞀郚の環境が䜿えるず蚀っおも、環境によっおはそのたたでは䜿えないかもしれないんでしょ ず蚀われたらそのずおりです。それなら各環境が POSIX.1-2024 に準拠したず発衚するたで䜿えないじゃんずなりたすが、ちょっず埅っおください。い぀たで叀い POSIX 暙準芏栌を参照しおシェルスクリプトを曞く気ですか 倚くの環境は POSIX に準拠しおいるず明蚀しおいたせんし、POSIX の叀いバヌゞョンにしか準拠しおいない堎合がありたす。いくら埅っおも各環境がどの POSIX のバヌゞョンに察応しおいるかなんお、䞀郚を陀いお公衚されるこずはありたせん。POSIX 暙準芏栌は POSIX が暙準芏栌ずしおたずめたただの文曞でしかなく、珟実の Unix/Linux の動䜜は曞いおありたせん。POSIX は特定のバヌゞョンのPOSIX に準拠しおいる環境ず同じバヌゞョンのPOSIX に準拠しおいるアプリケヌションの組み合わせであれば、別の環境ずの間に移怍性が実珟できるはずだず䞻匵しおいるだけで、各 Unix/Linux 間に互換性があるこずを保蚌しおいたせん。じゃあ䞀䜓どの環境がどの POSIX のバヌゞョンに準拠しおいるんだずいう話になりたすが、正匏に公衚されおいるのは次の環境だけです。

OS 準拠バヌゞョン 補足
macOS version 14.0 POSIX.1-2001 (SUSv3)
IBM AIX 5, 6, 7.1 POSIX.1-2001 (SUSv3) サポヌト終了OS
Solaris 10, 11 POSIX.1-2001 (SUSv3) UNIX認蚌の有効期限切れ
HP-UX 11i V3 B.11.31 POSIX.1-2001 (SUSv3)
INTEGRITY POSIX.1-2003 POSIX.1-2001の修正版

IBM AIX 7.2 以䞊 POSIX.1-2008 (SUSv4)
Solaris 11.4 POSIX.1-2008 (SUSv4) UNIX認蚌の有効期限切れ

ただなし POSIX.1-2024 (SUSv5)

各 Linux 明蚀なし
各 BSDç³»Unix 明蚀なし

POSIX.1-2024 は出たばかりだから、しばらくは䞀぀前の POSIX.1-2008 を参照しようず考えるかもしれたせん。しかし macOS などはさらに前の POSIX.1-2001 たでの察応しか公衚しおいたせん。Solaris は以前は UNIX の認蚌を受けおいたので䞀応 POSIX に準拠しおいるず分類しおいたすが、実際には UNIX 認蚌の曎新を行っおおらず有効期限切れずなっおいたす。぀たりこれたでの最新である POSIX.1-2008 に準拠しおいるず認められおいるのは事実䞊 IBM AIX 7.2 以降しかないずいうこずです。終息間近の HP-UX が曎新するずは考えにくいですし、macOS が UNIX の認蚌を受けた経緯を読む限り蚎蚟察策でしかないため、macOS は 20 幎以䞊前の叀い POSIX 準拠のたたで、公匏には最新の POSIX のバヌゞョンには远埓しないのではないかず私は考えおいたす。

macOS が POSIX.1-2001 たでしか察応しおいないずいうのは、あくたで Open Group が行っおいる UNIX の認蚌での話です。実際には POSIX.1-2008 にほが準拠しおいたずしおも䞍完党であるずかお金がかかる認蚌テストを行っおいないだけずいう堎合もありたす。POSIX.1-2024 に準拠しおいないずいうのは、POSIX.1-2024 で暙準化された機胜がいっさい䜿えないずいう意味ではありたせん。ほずんどの機胜が䜿えたずしおも認蚌テストに合栌しなければ準拠しおいないずしお扱われたす。macOS の倚くのコマンドは FreeBSD 版を導入しおおり、FreeBSD は新しい暙準芏栌ぞの察応を継続しお行っおいたす。したがっお macOS がバヌゞョンアップするたびに新しい機胜は増えおいたす。ただし macOS の sh は FreeBSD sh ではなく叀い bash なので POSIX.1-2024 に準拠するのであれば䜕かしらの察応が必芁です。叀いずはいえ高機胜な bash から䜎機胜な FreeBSD sh に倉曎するず互換性が保たれないため単玔に倉曎するこずはたず考えられたせん。倚くのコマンドはすでに POSIX.1-2024 に察応しおいおも sh が非察応なら POSIX.1-2024 に準拠ず公衚されるこずはありたせん。macOS の sh が今埌どうなるのかは珟時点では誰にもわかりたせんし、各 Linux ディストリビュヌションやその他の BSD ç³» Unix も POSIX にほが準拠しおいるず蚀われおいたすが、しかしどこたで準拠しおいるかは䞍明です。

実は getconf コマンドを䜿甚しお各 Unix/Linux が察応しおいる POSIX のバヌゞョンを調べるこずができたす。

OS _POSIX_VERSION
macOS 13.4 200112
FreeBSD 14.0 200112
NetBSD 10.0 200112
OpenBSD 7.5 200809
Ubuntu 22.04 200809

FreeBSD では 2024-05-31 に 200112 から 200809 ぞの倉曎がようやく行われたした䞀床間違えお 200808 ず曞いおしたっおいたすが。

macOS は FreeBSD のナヌザヌランドのコマンドを䜿甚しおいるため、そのせいで 200112 のたただった可胜性も考えられたすが、シェルやカヌネルは FreeBSD のものではないため、FreeBSD が倉曎になったからず蚀っお macOS が曎新されるずは限らないでしょう。Solaris 10 ず 11 ではディレクトリごずに準拠バヌゞョンが異なるバむナリが配眮されおおり以䞋のようになりたす。Solaris では適切な POSIX のバヌゞョンに準拠する環境を、環境倉数 PATH を蚭定しお䜜る必芁がありたす。デフォルトの /usr/bin/getconf PATH では䞀぀前のバヌゞョンを参照しおいるこずに泚意しおください。

  • Solaris 10
    • /usr/bin/getconf
      • _POSIX_VERSION: 199506
      • PATH: /usr/xpg4/bin:/usr/ccs/bin:/usr/bin:

    • /usr/xpg4/bin/getconf
      • _POSIX_VERSION: 199506
      • PATH: /usr/xpg4/bin:/usr/ccs/bin:/usr/bin:

    • /usr/xpg6/bin/getconf
      • _POSIX_VERSION: 200112
      • PATH: /usr/xpg6/bin:/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:

  • Solaris 11
    • /usr/bin/getconf
      • _POSIX_VERSION: 200809
      • PATH: /usr/xpg6/bin:/usr/xpg4/bin:/usr/bin:

    • /usr/xpg4/bin/getconf
      • _POSIX_VERSION: 198808
      • PATH: /usr/xpg4/bin:/usr/bin:

    • /usr/xpg6/bin/getconf
      • _POSIX_VERSION: 200112
      • PATH: /usr/xpg6/bin:/usr/xpg4/bin:/usr/bin:

    • /usr/xpg7/bin/getconf
      • _POSIX_VERSION: 200809
      • PATH: /usr/xpg7/bin:/usr/xpg6/bin:/usr/xpg4/bin:/usr/bin:


このように察応しおいる POSIX のバヌゞョンは調べるこずができたすが、あくたでシステム党䜓の話であり、個々のコマンドの察応状況はわかりたせんし、各 Unix/Linux で 特定の POSIX のバヌゞョンに準拠した環境を䜜る方法はさたざたです。ここからの結論は、それぞれの環境でどの機胜が䜿えるかなんお、昔から自分で調べないずわからないこずだずいうこずです。POSIX ずいう暙準芏栌があったずしおも、珟実の実装は最新の POSIX に準拠しおいない堎合やバグで正しく動かない堎合もありたす。そもそも POSIX に準拠しおいる実装の間でも動䜜が異なるためPOSIX は䞀郚の仕様で動䜜の違いを蚱容しおいる、POSIX ずいう暙準芏栌があったからず蚀っお、珟実の実装で 100% の互換性が保蚌されおいるわけではありたせん。100% の互換性を保蚌するのであれば、それはアプリケヌションシェルスクリプトを開発するプログラマの圹目です。

ね POSIX に準拠しおどの環境でも動くシェルスクリプトを開発するのは倧倉でしょ

安易に POSIX に準拠しおシェルスクリプトを曞けずか、そのコマンドやオプションは POSIX で芏定されおないからうんぬんかんぬんずいう人がいたすが、POISX を参照しお本圓に移怍性があるシェルスクリプトを曞いた人なんおほずんどいなくお、倧抵の堎合は問題になる曞き方がたたたた含たれおいなくお、たたたた動いおいるように芋えるだけです。本気でどの環境でも動くシェルスクリプトを開発するのは、他の蚀語に比べるずずおも倧倉なんです。テストを自動化するテストフレヌムワヌクなしにやれるようなものではありたせん。だから私は ShellSpec を䜜りたしたし、普通の人はこんなこずやらなくおいいですよ

POSIXの目的

POSIX ずは Portable Operating System Interface の略でアプリケヌションをさたざたな OS に移怍しやすくするために OS のむンタヌフェヌスを暙準化したものです。しばしば POSIX は Unix を䜜るための仕様だずか勘違いされおいたすが、POSIX の目的は Unix 以倖を含むさたざたな OS ぞのアプリケヌションを移怍できるようにするこずです。POSIX の目的は以䞋に蚘されおいたす。

  • アプリケヌション指向
  • 実装ではなくむンタヌフェヌスラむブラリ関数ずシステムコヌルは区別なし
  • C蚀語仕様は ISO C 暙準で指定されおいる暙準 C 蚀語の「甚語」で蚘述される
  • スヌパヌナヌザヌなし、システム管理なし
  • 最小限のむンタヌフェヌス、最小限の定矩
  • 幅広く実装可胜
  • 過去の実装に察する最小限の倉曎
  • 既存のアプリケヌションコヌドに察する最小限の倉曎

この暙準の開発者は、以䞋を含む既存のシステムや朜圚的なシステムを含む幅広い範囲で、指定されたすべおの機胜を実装できるように努めた

  • オリゞナルの UNIX システムコヌドから掟生した珟圚の䞻芁システムすべお
  • オリゞナルの UNIX システムコヌドに由来しない互換システム
  • たったく異なるオペレヌティングシステム䞊でホストされる゚ミュレヌション
  • ネットワヌク化されたシステム
  • 分散システム
  • 幅広いハヌドりェア䞊で動䜜するシステム

POSIX は「たったく異なるオペレヌティングシステム䞊でホストされる゚ミュレヌション」で実装できるよう暙準芏栌が䜜られおいたす。぀たりこれは Windows 䞊の Cygwin や WSL ずしお実装しおも構わないずいうこずです。POSIX が求めおいるのは Unix が持っおいた OS のむンタヌフェヌスを実装しお「Unix 甚のアプリケヌションを移怍しやすくするこず」であり、Unix ずしおの性胜や信頌性を実珟した OS の開発を求めおいるわけではありたせん。もし仮に䞀から OS を䜜るずしお POSIX に完党に準拠させお開発したずしおも、皆が想像するような Unix のような OS を䜜るこずはできたせん。なぜなら Unix に備わっおいるはずのシステム管理ハヌドりェア管理やナヌザヌ管理など、簡単に蚀えば root 暩限が必芁なものは POSIX で暙準化の察象範囲ではないからです。Windows で sudo コマンドがようやく利甚できるようになったず話題になりたしたが、sudo コマンドなどは明らかに POSIX で暙準化されるわけがないコマンドです。

りむンドりシステムも POSIX に含たれおいないので、知っおの通り Unix であるはずの macOS の GUI は他の Unix ずは党く異なる独自仕様です。GUI は Unix 的ではないずいうのが macOS が優れおいる理由の䞀぀です。もし OS を䜜るために必芁なものすべおが POSIX の察象範囲に含たれおいたずしたら、それは Unix を䜜るための暙準芏栌になっおしたい Unix 以倖の OS䟋えば Windowsは OS を Unix に䜜り倉えない限り POSIX に準拠させられなくなっおしたいたす。OS にも倚様性があったほうが良いでしょう Unix ç³» OS の間でしか移怍性がないのであれば、それは移怍性がある OS のむンタヌフェヌスではなく、単なる Unix のむンタヌフェヌスです。POSIX は Unix の実装を参考に䜜られたしたが、䜜られた OS のむンタヌフェヌスは Unix に限定したものではないのです。ただし POSIX の拡匵芏栌である SUS (Single Unix Specification) は、認定テストに合栌するず「Unix を名乗る」暩利が䞎えられるずいう暙準芏栌です。ある意味 Unix を䜜るための暙準芏栌ず蚀えたすが、その内郚実装は Unix のような OS でなくおも構いたせん。理屈の䞊では認定テストに合栌さえすれば、珟圚の Windows の姿のたた Unix を名乗るこずだっおできたす。POSIX には䜕かをカヌネルで実装しなければならないなどずは定矩されおいないので、Unix を名乗るために Windows のカヌネルを Linux や Unix に倉曎する必芁はありたせん。そもそも POSIX はカヌネルのシステムコヌルずラむブラリ関数の区別を意図的にしおいたせん。

POSIX 暙準芏栌はすでに存圚する Unix/Linux を元に䜜られおいたす。POSIX 暙準芏栌を元に Unix/Linux が䜜られおいるわけではありたせん。䟋えば今回の暙準芏栌で远加された timeout コマンドの仕様は OpenBSD (FreeBSD) のマニュアル (man ペヌゞ) から取っおきたものであるこずが明蚘されおいたす。参考

Add the timeout utility.
Here is the current manual page as present on OpenBSD, taken from
FreeBSD, under 2-clause BSD license:

このように POSIX 暙準芏栌は実圚する Unix/Linux の man ペヌゞや実際の動䜜を元に䜜られおいたす。POSIX が行っおいる暙準化ずいうのは、仕様を䜜るこずではなく実圚する Unix/Linux の仕様をアプリケヌションの移怍性の芳点から圹に立぀ようにたずめるこずです。POSIX に曞かれおいるのは、どの環境でも党く同じ動きをするこずが保蚌されたコマンドずオプションの䞀芧ではありたせん。POSIX に曞かれたコマンドずオプションだけを䜿えばそれだけで移怍性が実珟できるずいう単玔な話ではなく、プログラマは移怍䜜業を行う必芁がありたす。POSIX にはアプリケヌションシェルスクリプトを含むを他の OS に移怍するずきに、各 OS の互換性がない郚分などの䜕に気を぀けなければならないかが曞かれおおり、POSIX を読んで実際の環境の動䜜を調べお 「どの環境でも動くように䜜る䜜業を行う」のはプログラマの仕事です。どの環境でも動く移怍性が高いアプリケヌションを䜜るずきに、プログラマが読んで圹に立぀ものが POSIX ずいう暙準芏栌曞なのです。

POSIX 暙準芏栌で特に圹立぀のは「未指定」や「実装定矩」ず曞いおある郚分です。「未指定」や「実装定矩」ず曞いおある郚分は、各 Unix/Linux で動䜜が違うずころが刀明しおいるずいう意味なので、実際の環境での動䜜を調べなければいけない郚分ずしお圹に立ちたす。䟋えば今回の改定では、od コマンドで -A n を指定したずきにデヌタの最終行の次にアドレスだけの行が出力されるかされないかが明確に曞かれおいないずいう指摘があり修正されたした参考。改定によっお「『出力されるかされないかは未指定である』ず明確になった」ので、POSIX 暙準芏栌を読んだプログラマはその事に気づいお、出力されおもされなくおも問題ないように䞡方の動䜜に察応するシェルスクリプトを曞くためのきっかけになりたす。POSIX 暙準芏栌がアプリケヌションを移怍するずきに圹に立぀ずいうのは、こういう話なのです。

各 Unix/Linux の動䜜は现かい動きが違いたすが、POSIX が未指定や実装定矩ず決めたから各 Unix/Linux がバラバラの動䜜で実装しおしたったのではありたせん。各 Unix/Linux で動䜜がバラバラだったから、POSIX は互換性を保぀ために仕様を倉曎せず「未指定や実装定矩ずいう仕様」で暙準化しおプログラマに察応を促すしかなかったのです。POSIX は各 Unix/Linux 間で 100% の互換性を保蚌する暙準芏栌ではなく、100% の環境で動くアプリケヌションを䜜りたいのであればプログラマが頑匵るしかありたせん。そのような面倒さをなくすために、他の蚀語では 100% の互換性を実珟しおいない POSIX 局の䞊に、蚀語やラむブラリによる環境の違いを吞収する局を䜜るこずで、ほが 100% の互換性を20幎も前から実珟しおいたす。この仕組みによっお䞀般のプログラマの開発の負担を枛らしながら、POSIX 環境以倖を含むすべおの環境でアプリケヌションを動かすこずを実珟しおいたす。シェルスクリプトを含むアプリケヌションの移怍性を高めるためには環境䟝存が高い Unix/Linux の基本機胜POSIX むンタヌフェヌスや POSIX コマンドなどを含むを「盎接」䜿わないこずが重芁な考え方です。私が目指しおいるのは POSIX を意識するこずなく、他の蚀語䞊みの移怍性をシェルスクリプトの䞖界にもたらすこずです。

POSIXの成り立ち

POSIX は IEEE 1003 暙準芏栌に察するわかりやすい呌び名で、GNU プロゞェクトで有名な Richard Stallman が名前を考案したした。それたで暙準芏栌の策定䞭は誰かが名付けた IEEEIX ず呌ばれおおり、Portable Operating System ずいうサブタむトルが付いおいたした。このサブタむトルの略である POS に IEEEIX ず同じ IX を組み合わせお䜜られた甚語が POSIX です。おそらく IX は圓時の UnixMicrosoft が開発した䞖界初の商甚 Unix である Xenix などが末尟に IX を぀けた名前をよく䜿っおいたこずから来おいるず思われたす。珟圚では I は Interface の略ずしお POSI ずなり、最埌の X には特に意味はないずされおいたす。

暙準化は 1970 幎代埌半から 1980 幎代前半にかけお倚数のコンピュヌタメヌカヌが独自に開発しおいた Unix 間で互換性が䜎くなり、それぞれの Unix 甚にアプリケヌションを開発するのが倧倉になったために始たりたした。「独自に開発しおいた Unix」ずいうのは、AT&T から Unix のコヌドずラむセンスを賌入するか、事実䞊のオヌプン゜ヌスである BSD Unix を元に、自分たちが販売するコンピュヌタ甚に Unix を移怍するずいう意味です。各 Unix 間の互換性が䜎くなった理由は Unix を搭茉したコンピュヌタを販売するコンピュヌタメヌカヌは Unix を移怍するだけではなく、他瀟よりもより優れた Unix ずしお改良を加えるず同時に API を顧客を囲い蟌むためのベンダヌロックむンずしお利甚したからです。圓時の Unix の倚くは OS 単䜓で配垃されるものではなくコンピュヌタの付属品であり゜ヌスコヌドは非公開でした。そのため各 Unix ベンダヌの独自の修正を他瀟が取り蟌むこずはできず、䌌たような機胜を実装するのが粟䞀杯で、完党に同じ仕様で実装できないため互換性䞊の問題が発生したした。今のようにオヌプン゜ヌスが圓たり前の䞖界になるのは 1990 幎代の埌半以降です。

暙準化はコンピュヌタメヌカヌではなくアプリケヌション開発者によっお掚進されたした。POSIX の前身ずなる暙準化団䜓がナヌザヌグルヌプの /usr/group です。/usr/group は 1981 幎頃に暙準化委員䌚が蚭立され、1984 幎に /usr/group 暙準芏栌が策定されたした。しかしさたざたな理由でアメリカ政府が /usr/group を公匏の暙準化団䜓ずみなさなかったため、IEEE のスポンサヌのもずで再始動し 1988 幎に策定されたのが POSIX です。この経緯から掚枬するにコンピュヌタメヌカヌは移怍性の向䞊にはあたり乗り気ではなかったず思われたす。だっおアプリケヌションがどの Unix でも動くのなら、他瀟補コンピュヌタの Unix に乗り換えやすくなるでしょう Unix ベンダヌは圓時のアメリカ政府が玍入条件ずしお POSIX 準拠ただし C 蚀語むンタヌフェヌスの範囲でシェルやコマンドは含たないを指定したために POSIX に準拠せざるを埗なかったのだず思われたす。POSIX 準拠はそれはそれで Unix 搭茉コンピュヌタを売るずきのアピヌルポむントにはなりたす。アメリカ政府は本圓は Unix を指定したかったようなのですが特定のベンダヌに䟝存しない暙準芏栌は POSIX だけでした。その結果、Windows NT は Unix ではないにも関わらず POSIX 準拠ずしお開発され玍入条件を満たすこずになりたす。結局のずころ Windows NT は POSIX 準拠でしたが Unix ではないため Unix の代替にはなりたせんでした。珟圚の Windows に搭茉された WSL は POSIX 準拠を超えた Linux 互換機胜であるためずおも人気がありたす。ちなみに POSIX がアメリカ政府の玍入条件だったのは過去の話で珟圚は廃止されおいたす。圓時のコンピュヌタメヌカヌが Unix に独自機胜を搭茉しおベンダヌロックむンを目指しおいたのはある意味正しかったのかもしれたせん。Linux ず GNU コマンドがおおむね POSIX に準拠しお䜜られ Unix から Linux ぞ乗り換えがしやすくなった結果、珟圚の Linux の普及に぀ながり商甚 Unix の䞖界は倧きく衰退したからです。

勘違いされやすいのですが、POSIX は圓初から Unix颚の OSを䜜るための暙準芏栌ずしおは䜜られたせんでした。POSIX はアプリケヌションの移怍が焊点であり、POSIX が想定しおいる OS には Unix 以倖の OS も含たれおいたす。POSIX は Unix を手本にしお䜜られたしたが、Unix が持っおいたシステム管理機胜ハヌドりェア管理機胜やナヌザヌ管理機胜はばっさり削陀されおいたす。これらの機胜が POSIX に含たれおいるず、POSIX に準拠しお動くアプリケヌションを増やしたいだけなのに Unix を䜜らなければならなくなっおしたいたすよね POSIX の範囲ではシステムにログむンする機胜もナヌザヌを䜜成する機胜もありたせん。これらはアプリケヌションを動かすうえで暙準化する必芁がないためです。そもそもシステム管理機胜はコンピュヌタメヌカヌが販売する商甚 Unix によっお違うのが圓たり前なので暙準化しようず思っおもできたせん。POSIX は暙準化できないものは暙準化したせん。特にグラフィカルナヌザむンタフェヌスやデヌタベヌスむンタヌフェヌスは明確に察象倖ず蚘茉されおいたす。POSIX の機胜だけではたずもに Unix/Linux を䜿うこずや、その䞊で動く゜フトりェア開発は䞍十分なのです。

OS の機胜は元より環境䟝存が激しい機胜です。だからこそある皋床の暙準化が必芁になりたした。特定の OS に䟝存しおいない倚くのコマンドやプログラミング蚀語は POSIX の暙準化の察象倖です。なぜなら OS の機胜ではないからです。POSIX にずっおはそれらはアプリケヌションです。倚くのコマンドやプログラミング蚀語が POSIX で暙準化されおいないからず蚀っお、シェルスクリプトや C 蚀語を䜿わなければ POSIX に暙準したアプリケヌションが䜜れないずいうこずはありたせん。どのようなコマンドや蚀語を䜿ったずしおも内郚で OS の機胜を䜿う時に POSIX むンタヌフェヌスを呌び出しおいれば POSIX 準拠のアプリケヌションず蚀えたす。䟋えば curl や jq や SQLite は POSIX コマンドではありたせんが、POSIX 準拠のコマンドで移怍性が高くむンストヌルすればどの環境でも䜿えるコマンドずしお有名です。このような POSIX コマンド以倖の POSIX 準拠コマンドやプログラミング蚀語を䜜るために、POSIX 暙準芏栌が䜜られたした。今では POSIX のおかげで倚くのコマンドやプログラミング蚀語があらゆる OS で動くようになり、それらを利甚するこずで簡単にどの環境でも動くシェルスクリプトやアプリケヌションを䜜るこずができるようになったのです。

POSIXの改定履歎

POSIX に関する暙準芏栌はいく぀もあり混乱するため、ここにPOSIXの改定履歎をたずめたした。

2000 幎頃たで

初期の POSIX の暙準化は IEEE の PASC (Portable Application Standards Committee) によっお行われおいたす。

POSIX は 1988 幎C 蚀語むンタヌフェヌスたたは 1992 幎シェルずコマンドに暙準化されお以降、䜕床か機胜远加を含む改定が行われたした。初期の POSIX 芏栌は POSIX.nたたは IEEE 1003.nのような呜名芏則でした。䟋えば POSIX.1 が C蚀語むンタヌフェヌス、POSIX.2 がシェルずコマンドずいった感じです。そしお POSIX.1-1988 のように埌ろにハむフンで幎号を付けたものが暙準芏栌の名前でした。たた POSIX.2 ぞの远加機胜は POSIX.2a-1992 のように n のあずにアルファベットが付加されおいたした。このような呜名芏則は 2000 幎頃たで䜿われたした。この頃の POSIX の掻動は掻発で、最終的にどこたでの掻動を想定しおいたのかはっきり調べきれおいたせんが、怜玢するず POSIX.27C++ バむンディングのようなものも蚈画にあったようです。ただしその倚くが撀回されるか POSIX.1 に取り蟌たれお消えたした。

幎 コア機胜 远加機胜 XPG / SUS ←別の暙準芏栌→ SVID
1984 (/usr/group)
1985 XPG1 (Issue 1) SVID1
1987 XPG2 (Issue 2) SVID2
1988 POSIX.1-1988
1989 XPG3 (Issue 3) SVID3
1990 POSIX.1-1990
1992 POSIX.2-1992 POSIX.2a-1992 XPG4 (Issue 4)
1993 POSIX.1b-1993
1994 POSIX.2d-1994 XPG4v2 (Issue 4 version 2)
1995 POSIX.1c-1995 SUSv1 (UNIX 95) SVID4
1996 POSIX.1-1996
1997 SUSv2 (UNIX 98, Issue 5)
1998 POSIX.13-1998
1999 POSIX.1d-1999
POSIX.2b draft
2000 POSIX.1g-2000
POSIX.1j-2000
POSIX.1q-2000

POSIX は特定の Unix ベンダヌのための暙準芏栌ではありたせん。䞭立的で圓時の二倧 Unix であった BSD Unix ず UNIX System V の䞡方を考慮しお䜜られた暙準芏栌です。䞡方を考慮しおいるのであれば、POSIX に準拠すれば BSD Unix ず UNIX System V の䞡方で動くようになるず思うかもしれたせんが、結局のずころ䞡方に共通するものしか暙準化ができないずいうこずなので、POSIX で暙準化された範囲でできるこずは少なくなりたす。暙準芏栌は POSIX だけではありたせん。XPG (X/Open Portability Guide) は X/Open ずいう団䜓による暙準芏栌です。X/Open は POSIX よりも広い範囲の技術を察象にしおおり、その範囲には䟋えば SQL やりむンドりシステムなどが含たれおいたす。ただし X/Open が暙準芏栌のすべおを䞀から策定しおいるずいうわけではなく、他の暙準芏栌を参照しお䜜られおいたす。XPG4 の䞭の䞀郚である基本仕様は X/Open CAE Specification (CAE = Common Applications Environment) ず呌ばれおおり、POSIX の暙準化の範囲に近く C 蚀語むンタヌフェヌスやシェルやコマンドなどがドキュメント化されおいたす。

X/Open は AT&T から Unix の暩利を買い取った Novell から Unix ブランドを譲枡され、他の団䜓ずの合䜵などを経お The Open Group ず名前を倉え、珟圚は SUS (Single UNIX Specification) ずいう暙準芏栌を発行しおいたす。この SUS が Unix であるず認められるために必芁な暙準芏栌です。䟋えば SUSv1 に認定された Unix は UNIX 95 ずいうブランド名を名乗るこずができたす。SUS は X/Open CAE Specification の埌継ずしおそのドキュメントの䞀郚から構成されおいたす。぀たり XPG は幅広い技術を察象ずしおいたしたが、SUS の察象ずする範囲はそれよりも小さく POSIX の察象範囲を少し超える皋床に近づきたした。ちなみに XPG は OS のむンタヌフェヌスずしお SVID (System V Interface Definition) ずいう別の暙準芏栌を参照しおおり、SVID はその名の通り UNIX System V のむンタヌフェヌスを定矩した AT&T が策定した暙準芏栌です。そのため XPG ず SUS で暙準化された OS のむンタヌフェヌスは System V ç³» Unix に近いものずなっおいたす。

2000 幎以降

POSIX は元は IEEE による暙準芏栌ですが、珟圚1997幎以降は POSIX の改定䜜業を行うために蚭立された共同技術ワヌキンググルヌプである Austin Group によっお改定䜜業が行われおいたす。POSIX ず呌ばれおいる暙準芏栌は、IEEE (PASC)、ISO/IEC (JTC 1/SC 22)、The Open Group の3぀の団䜓がそれぞれ発行しおいる暙準芏栌のベヌスずしお採甚しおおり、それぞれの組織のメンバヌが Austin Group に参加しおいたす。Austin Group の議長は The Open Group の Andrew Josey です。ちなみに Austin Group ぞは誰でも無料で参加できるメヌリングリストぞの登録が必芁ので、誰でも POSIX の暙準芏栌の内容に口を出すこずができたす。もちろん各 Unix/Linux の関係者で参加しおいる人もいるはずです。誰でも新しい暙準芏栌を POSIX に提案するこずができたすが「発明」今たでに誰も実装したこずがない玠晎らしい新機胜は採甚されないこずに泚意しおください。POSIX の暙準化ずは新しい機胜を䜜るこずではなく、既存の実装の動䜜を明文化するこずです。

SUS は元は POSIX ずは独立した暙準芏栌でしたが、Austin Group によっお POSIX ずの統合䜜業が行われ、POSIX.1-2001 で POSIX 暙準芏栌の拡匵芏栌ずしお統合されたした。IEEE が発行する暙準芏栌は有料ですが、The Open Group は SUS ずしお無料で公開しおおり、POSIX ず統合された SUS ずいう圢で私達は無料で POSIX 暙準芏栌曞を参照するこずができたす。SUS のみに存圚しおいた機胜は、XSI オプションず呌ばれる拡匵機胜ずしお「POSIX に準拠するだけなら実装は必須ではない仕様」ずしお蚘茉されおいたす。たた SUS には POSIX には組み蟌たれなかった X/Open Curses ずいった仕様もありたす。POSIX に含たれおいる XSI オプションは元は UNIX System V の仕様です。SUS が Unix ず認められるために満たさなければいけない仕様ずはBSD Unix ではなくUNIX System V ずの互換性を実珟するための仕様であるこずを意味しおいたす。蚀い換えるず XSI オプションは BSD ç³» Unix ずの互換性が䜎い郚分です。BSD ç³» Unix では XSI オプションは実装されおいない可胜性があるだけではなく、暙準化された内容ずは異なる仕様で実装されおいる可胜性もありたす。XSI オプションが䜕かを知らないず、POSIX 暙準芏栌にXSI オプションずしお蚘茉されおいるのだから移怍性がある機胜なのだろう勘違いしがちですが、XSI オプションの郚分は移怍性がないかもしれない機胜なのです。Ubuntu のずあるペヌゞにはこうありたす。

We recommend that developers of shell scripts adhere to the POSIX standard, omitting those items flagged as XSI extensions.

èš³ 私達はシェルスクリプトの開発者たちは POSIX 暙準に準拠し、XSI 拡匵ずしおフラグが぀けられた項目を省略するこずをおすすめしたす。

POSIX.1-2001 以降では埓来の POSIX.n ずいう呜名芏則がほがなくなり、POSIX.2 は POSIX.1 に統合されたした。぀たり珟圚の POSIX 暙準芏栌は POSIX.1-xxxx ずいう呜名芏則のみですリアルタむムコントロヌラヌシステムのプロファむルを定めた POSIX.13 を陀く。この頃にはもう POSIX の開発はメンテナンスのようなものずなり倧きな機胜远加を行うずいう考えはなくなっおいるようです。UNIX の暙準芏栌は POSIX の暙準芏栌に察応しお SUSv3、SUSv4 のような名前ずなっおいたす。SUS が POSIX に統合された POSIX.1-2001 (SUSv3) の時点では倚くの XSI オプションがありたしたが、POSIX.1-2008 (SUSv4) では倚くの XSI オプションが暙準機胜ぞず倉曎になっおいたす。これは元々 UNIX System V ずの互換性の仕様だったものが BSD ç³» Unix や Linux でも実装されお、移怍性があるから XSI オプションずする必芁がなくなったこずを意味しおいたす。逆に蚀えば珟圚も XSI オプションのたた残っおいるものは移怍性に関しおさらに泚意が必芁だずいうこずです。

Year 暙準芏栌 现かい修正版 SUSPOSIX に統合された拡匵芏栌
2001 POSIX.1-2001 SUSv3 (UNIX 03, Issue 6)
2003 POSIX.1-2001 TC1 : 2003 Edition
2004 POSIX.1-2001 TC2 : 2004 Edition
2008 POSIX.1-2008 SUSv4 (UNIX V7, Issue 7)
2013 POSIX.1-2008 TC1 : 2013 Edition
2016 POSIX.1-2008 TC2 : 2016 Edition
2017 POSIX.1-2017 : 2018 Edition
2024 POSIX.1-2024 SUSv5仮 (UNIX V8, Issue 8)
:
20xx POSIX.1-20xx SUSv6仮 (UNIX V9, Issue 9)

现かい修正版 (TC: Technical Corrigendum) では、暙準芏栌の間違いの蚂正を行ったり、将来の倧芏暡な暙準芏栌の改定で行われるかもしれない内容を「将来の方向性」(FUTURE DIRECTIONS) に远蚘したりしおいたす。「将来の方向性」が実珟するには各Unix/Linuxの実装者がその方向性に同意しお実装しなければいけないので必ずしも実珟するずは限りたせん。あくたで POSIX が考えおいる将来像です。POSIX.1-2017 は 2018 幎に暙準芏栌が期限切れになるのを防ぐために公開された改定版です。厳密には今回の改定である POSIX.1-2024 の䞀぀前は POSIX.1-2017 になるのですが、POSIX.1-2017 の内容は POSIX.1-2008 2016 Edition (POSIX.1-2008 + TC1 + TC2) ず同䞀であるため本蚘事では倧幅な改定には含めおおらず、今回の改定は 16 幎ぶりの倧幅な改定ずいうこずになりたす。

ちなみに Austin Group では POSIX 暙準芏栌の各バヌゞョンはコヌドネヌムのような感じで Issue N のような名前で呌ばれおいたす。これは The Open Group の前身である X/Open 時代から継続しおいる名前ですXPG1 = Issue 1。现かい改蚂版は区別するこずなく Issue N ず呌ばれおおり、正匏な暙準芏栌の名前を䜿うよりもわかりやすいです。次回10幎埌ぐらいの改定版は Issue 9 ず呌ばれおいたす。Issue N は暙準芏栌の CHANGE HISTORY での改定履歎などでも䜿われおいたす。ちなみに Solaris 11 では /usr/xpg4/bin、/usr/xpg6/bin、/usr/xpg7/bin のようなディレクトリにそれぞれの暙準芏栌のバヌゞョンに適合したコマンドがむンストヌルされおいたすが、xpg6 や xpg7 のような名称は暙準芏栌の名前ずしおは正確なものではありたせん。

なぜOS暙準コマンドは充実しないのか

ここたで読んでくれた人ならすでに気づいおいるず思いたすが、Unix/Linux の OS 暙準コマンドが䟿利で充実した物にならないのは、OS の開発者がそれらを䜜る必芁がないからです。POSIX の移怍性の芁は C 蚀語むンタヌフェヌスです。Unix/Linux の OS の開発者からすれば C 蚀語むンタヌフェヌスさえ暙準化されおいれば、それ䜿っお誰でもさたざたなアプリケヌションが䜜れるわけで、自分たちで OS のコマンドを充実させる必芁がありたせん。

OS 暙準コマンドは OS の䞀郚であるため環境䟝存が激しくなりやすいずいう問題もありたす。特に BSD ç³» Unix や System V ç³» Unix では OS に組み蟌たれたコマンドは、それぞれ別々に開発しおいこうずする傟向にありたす。いく぀かの䟋倖もありたすがコヌドの修正を䞊流のプロゞェクトに集めお OS ずは独立しお育おおいこうずはしたせん。元々 OS の開発ずいうのはそういうものです。POSIX で OS のむンタヌフェヌスが暙準化されたず蚀っおも、POSIX が OS の仕様を䜜っおいるわけではないため、1990 幎代以降の OS の開発は、それぞれの OS で独立した開発です。

各 OS の開発者は、自分たちにずっお必芁なコマンドの実装は行いたすが、どの環境でも動く移怍性のある新しい OS のコマンドをみんなで䜜っおいこうずいう考えは持っおいたせん人によるずは思いたすが。せいぜい既存のコマンドに远加する機胜を、他の Unix/Linux のコマンドを真䌌しお実装する皋床です。移怍性がある新しい OS のコマンドが充実しないのだから POSIX で新しいコマンドが暙準化されるこずもありたせん。今回の倧幅な改定でも実際には䜕幎も前からどこかで実装されおいた機胜が倧半です。暙準化されたのは長い時間をかけおどの環境でも䜿えるようになった移怍性のあるわずかなコマンドや機胜だけです。

シェルスクリプトの分野がほずんど 1990 幎頃のたたで発展しおいないのは、POSIX で暙準化された OS のコマンドは暙準化されおいるから良いものなんでしょずいう考えや、移怍性が高いコマンドをむンストヌルするのが面倒だからず最初から䜿えるコマンドでそれだけを䜿っおシェルスクリプトを曞くのが良いこずだずいう間違った考えが広たっおいるからです。OS 暙準コマンドはこれからも充実するこずはありたせんし埌方互換性を維持するために倧きく改良されるこずはありたせん。したがっお人類が目指すべきなのは脱 POSIX コマンドです。POSIX コマンドがなくなるこずはありたせんがい぀たでも䞍䟿なたたなので、それを利甚しおシェルスクリプトを曞くのは、特定の OS に䟝存したシェルスクリプトを䜜るずきだけで十分です。䞀般のプログラマは POSIX を意識する必芁をなくしおいくべきです。将来的に POSIX を意識する必芁をなくすために、今はただ最䜎限完璧ではないが䟿利ずいう意味の移怍性を解説した POSIX を知る必芁がありたす。

シェルは䜕が倉わったか

最初に説明した通りシェルが倉わったず蚀っおもそれはあくたでPOSIXで暙準化されおいるシェル (POSIX sh) が倉わったずいう話です。远加された機胜はすでに bash や ksh などで実装枈みで、人によっおはおなじみの機胜ばかりです。

シェル蚀語自䜓の機胜

ここではシェル蚀語自䜓に远加された機胜を玹介したす。

ANSI C 文字列を解釈する $'...'ダラヌシングルクォヌトの远加

$'...'ダラヌシングルクォヌトは ANSI C のバックスラッシュを甚いた゚スケヌプシヌケンスを解釈する文字列です。

$ printf '%s\n' $'Hello\nWorld'
Hello
World

bash、ksh93、zshはかなり昔から察応しおいたす。FreeBSD shずNetBSD sh は最新版では察応しおいたす。ただし dash や OpenBSD sh ではただ察応しおいたせん。おそらくそのうち察応するでしょう。

2023-06-23 远蚘 dashに $'...' の機胜が 2024-06-22 に远加されたした。おそらく v0.5.13 以降で察応するこずでしょう。たたマルチバむト文字ぞの察応も行われおいたす。

察応しおいないシェルでは printf コマンドを䜿甚しお゚スケヌプシヌケンスを解釈するこずができたすが、倉数に代入したりコマンドの匕数に䜿甚する堎合はサブシェルを䌎うコマンド眮換を䜿甚する必芁があるため遅くなりたす。ダラヌシングルクォヌトはそのような問題を解決したものです。

䜙談ですが、 $'...' は tcsh でも 2022幎2月2日にリリヌスされた 6.24.00 以降で察応しおいたす。

case のフォヌルスルヌ (;&) の远加

倚くのシェルが察応しおいる、case コマンドのフォヌルスルヌ (;&) が暙準化されたした。以䞋のコヌドは、foo ず bar の䞡方を出力したす。

case foo in
  *foo*) echo foo ;& # 次の行のコマンドも実行される
  *bar*) echo bar ;; # bar にはマッチしおいないが実行される
esac

ちなみに bash はフォヌルスルヌに䌌おいるが次の条件刀定も行う ;&& が実装されおいたすが、こちらは POSIX では暙準化されおいたせん。おそらく ksh ず zsh で実装されおいないから候補にならなかったのではないかず考えられたす。

単語分割、IFS の仕様が詳现に定矩される

信じられないこずにこれたで単語分割、たたは IFS シェル倉数の仕様が明らかに䞍十分でした。POSIX.1-2024 では詳现に定矩されおおり、曞き盎しに近いレベルでかなりの量の文章が远加されおいたす。

どおりで POSIX 眺めおいおも IFS の现かい仕様がわからんかったはずだよ......

クォヌトを掚奚する文字の倉曎

シェル蚀語は文字をクォヌトせずにそのたた曞くこずができたすが、䞀郚の文字蚘号はクォヌトせずに䜿うず特別な意味を持ちたす。倚くの文字がクォヌトが必芁になっおいるため、逆にクォヌトせずに䜿える文字を䟋瀺したほうが簡単です。ここに挙げた蚘号以倖はクォヌトするこずを掚奚したす。よくわかなければ蚘号はすべおクォヌトする方針でもよいでしょう。

クォヌトせずに䜿甚可胜な文字
+ - . / : @ _

実装が必須ではないブレヌス展開ぞの考慮

䞀郚のシェルはブレヌス展開{1..10} や {a,b,c}.txt のようなものを実装しおいたすが、これたでの POSIX では文法的に受け入れられおいたせんでした。この拡匵機胜の実装が可胜になるように文法が修正されたした。たた「ブレヌス展開をサポヌトしおいるシェルではすべおの暙準的な単語展開の前に実行すべきである」ず明蚘されたした。ブレヌス展開がその他の展開のよりも埌に実行されるず予期せぬ結果をもたらす可胜性があるからです。

ブレヌス展開が他の展開より埌で実行された堎合の予期せぬ結果
$ zsh -c 'a="1." b=".10"; echo {$a$b}'
1 2 3 4 5 6 7 8 9 10

bash や POSIX モヌドの ksh93u+m では POSIX で暙準化されおいる通りブレヌス展開は最初に行われるので、このような予期せぬ結果は発生したせん。ただし次のように数倀の終了倀に倉数が䜿えないなど䞍䟿に感じる堎合がありたす。この問題は eval コマンドを䜿っお回避するこずができたす。

POSIX に準拠したオプション機胜のブレヌス展開の挙動
$ bash -c 'n=10; echo {1..$n}'
{1..10}

$ ksh -o posix -c 'n=10; echo {1..$n}' # ksh93u+mksh93は非察応
{1..10}

$ bash -c 'n=10; eval "echo {1..$n}"'
1 2 3 4 5 6 7 8 9 10

POSIX モヌドではない ksh や zsh では次のような動䜜になりたす。

POSIX に準拠しおいないオプション機胜のブレヌス展開の挙動
$ ksh -c 'n=10; echo {1..$n}'
1 2 3 4 5 6 7 8 9 10

$ zsh -c 'n=10; echo {1..$n}'
1 2 3 4 5 6 7 8 9 10

繰り返したすが、ここたで仕様が定矩されおいながらもブレヌス展開の実装は POSIX.1-2024 では必須ではありたせん。ただしブレヌス展開は POSIX で拒吊されおいるわけではなく、誰も暙準芏栌を曞いおおらず、詳现な議論耇数のシェルの動䜜を矛盟なく共通の文章で定矩できるかが行われおいないずいうだけなので、将来の POSIX で暙準化される可胜性が高い機胜ず考えられたす。

実装が必須ではない {fd}>file ぞの考慮

bash ず ksh で察応しおいるファむルディスクリプタ番号 10 以䞊を扱うための以䞋のような構文が蚱可されたした。

( echo "[fd: $fd] test" >&"$fd" ) {fd}>/tmp/log.txt

この機胜も POSIX.1-2024 ではオプション機胜であり実装は必須ではありたせんが、拡匵機胜ずしお実装しおも POSIX に違反しないように文法が蚱可されおいたす。

将来の方向性: 「.*」が「.」「..」に展開しないようになる

珟圚のシェルの実装では .* が . ず .. に展開される堎合ず展開されない堎合がありたす。倚くのシェルではデフォルトで . ず .. に展開されたすが、bash 5.2以降、ksh、mksh、zsh では展開されたせん。

dash、bash 5.1たで、yashなど
$ echo .*
. . .file.txt
bash 5.2以降、ksh、mksh、zshなど
$ echo .*
.file.txt

パス名䞀芧に . ず .. が含たれるこずに意味はなく、バグの原因になるずしお、POSIX.1-2024 では「. ず .. を無芖する堎合がある」ず明蚘され、将来のバヌゞョンでは「. ず .. を無芖するこずを芁求するかもしれない」こずが蚘茉されたした。

bash は 5.2 以降でデフォルトで . ず .. に展開されなくなりたした。そのためこれより . ず .. に展開されるシェルがあるこずに気づきにくくなりたす。. ず .. に展開されないのは方向性ずしおは正しいず思いたすが、移怍性があるシェルスクリプトを曞こうずする人にずっおは、この仕様に気づかないこずによるバグが発生する可胜性がありたす。なお以前の動䜜に戻すには shopt -u globskipdots を実行したす。

補足ですが、ls -a で . ず .. を含む隠しファむルず通垞のファむルの䞀芧を出力するこずができたすが、ls -A を䜿甚すれば . ず .. を無芖するこずができたす。-A オプションは POSIX.1-2008 で暙準化されおいたす。

コマンドの分類の詳现化

シェルに組み蟌たれたコマンドは、これたで「特殊シェルビルトむンコマンド」ず「通垞のシェルビルトむンコマンド」の2぀の分類しかありたせんでした。この分類は今も倉わっおいたせんが、宣蚀コマンドず内圚コマンドずいう新たな分類が远加されたした。シェルに組み蟌たれたコマンドは「特殊シェルビルトむンコマンド」「内圚コマンド」「通垞のシェルビルトむンコマンド」のいずれかに分類され、その䞭に「宣蚀コマンド」に該圓するコマンドがあるずいう関係です。

宣蚀コマンド (Declaration Utilities)

宣蚀コマンドずは「倉数ぞの代入を行う圢になっおいるタむプのコマンド」で、POSIX では export、readonly、特別な堎合の command が宣蚀コマンドずしお定矩されおおり、その他に実装が远加の宣蚀コマンドを提䟛しおいる堎合がありたすdeclare や typeset や local など

宣蚀コマンドずいう区別が必芁な理由は通垞のコマンド呌び出しず宣蚀コマンドで匕数の解釈が異なるためです。具䜓的な䟋を芋おいきたしょう。

通垞のコマンド env の堎合bashで実行
$ var='123 VAR2=456'
$ env VAR1=$var sh -c 'echo "$VAR1 : $VAR2"'
123 : 456
宣蚀コマンド export の堎合bashで実行
$ var='123 VAR2=456'
$ export VAR1=$var && sh -c 'echo "$VAR1 : $VAR2"'
123 VAR2=456 :

どちらも環境倉数に倀を蚭定しおその倀を出力するコヌドですが結果が異なっおいたす。これは単語分割による挙動の違いです。通垞のコマンドは倉数を参照するずきにダブルクォヌトされおいない堎合は単語分割が行われたす。぀たりスペヌス正確には IFS シェル倉数で指定された文字で分割され耇数の匕数が生成されたす。そのため前者の env コマンドの䟋は次のように解釈されたす。

通垞のコマンドは、単語分割により耇数の匕数に分割される
$ var='123 VAR2=456'
$ env VAR1=$var sh -c 'echo "$VAR1 : $VAR2"'
            ↓
$ env VAR1=123 VAR2=456 sh -c 'echo "$VAR1 : $VAR2"'

䞀方で宣蚀コマンドの堎合は単語分割が行われたせん。぀たり埌者の export コマンドの堎合は次のように解釈されたす。

宣蚀コマンドは、単語分割は行われず耇数の匕数に分割されない
$ var='123 VAR2=456'
$ export VAR1=$var && sh -c 'echo "$VAR1 : $VAR2"'
               ↓
$ export VAR1='123 VAR2=456' && sh -c 'echo "$VAR1 : $VAR2"'

ちなみに単語分割が行われないのは通垞の倉数代入でも同じです。

通垞の倉数代入は単語分割が行われない宣蚀コマンドず同等の動䜜
$ var="123 VAR2=456"
$ VAR1=$var && echo "$VAR1 : $VAR2"
123 VAR2=456 :

぀たり倉数ぞの代入の圢をした宣蚀コマンドは、通垞の倉数ぞの代入ず同じ挙動をするずいうこずです。他にも宣蚀コマンドでは次のように配列を扱ったりするこずができたす。通垞のコマンドではこのような匕数の曞き方をするず文法゚ラヌになるため宣蚀コマンドずいう区別が必芁なのです。

bashの堎合
foo() {
  local ary=(1 2 3)
}

宣蚀コマンドは POSIX シェルの元になった ksh88 の時点ですでに存圚しおいた抂念ですが、芋逃されおいたのか POSIX で暙準化されおいたせんでした。ちなみに Bourne シェルには倉数ぞの代入の圢をしたコマンドはありたせん。export コマンドや readonly コマンドは倉数の属性を倉えるこずしかできず、同時に代入するこずはできたせんでした。぀たり宣蚀コマンドは ksh88 で新しく远加された機胜ずいうこずです。bash、mksh、ksh、zsh、FreeBSD sh、OpenBSD shでも ksh88 ず同様の動䜜を行いたすが、すべおのシェルが宣蚀コマンドになっおいるわけではなく、dash 0.5.10 ずそれ以前、NetBSD shNetBSD 10.0時点、yash2.56時点では宣蚀コマンドではない挙動をしたす。そのため珟時点では export などで代入倀ずしお倉数を䜿う堎合はダブルクォヌトしおおいたほうが安党です。もちろん通垞の倉数代入であればダブルクォヌトはなくおも構いたせん。

# 珟時点では宣蚀コマンドでもダブルクォヌトしおおいた方が安党
export VAR1="$var"

# 通垞の倉数代入ならダブルクォヌトはなくおも良い
VAR1=$var

内圚コマンド (Intrinsic Utilities)

「内圚コマンド」は Intrinsic Utilities に察しお私が付けた蚳です。Intrinsic はシェルに「本来備わっおいる」ずいう意味がここでは䞀番的確だず思いたすが、「本質的コマンド」ずか「固有コマンド」ではすっきりしないので自分でもあたり満足しおいないのですが内圚コマンドず蚳しおいたす。内郚コマンドずも蚳せるず思いたすが、それだずシェルビルトむンコマンドず混同しおしたうので。

内圚コマンドの説明の前にたず前提知識ずしおシェルビルトむンコマンドの話です。シェルに組み蟌たれたコマンドをシェルビルトむンコマンドず呌びたすが、倧きく分けお「特殊シェルビルトむンコマンド」ず「通垞のシェルビルトむンコマンド」の぀に分類するこずができたす。特殊シェルビルトむンコマンドはシェルの機胜ず深く結び぀いおいる以䞋のコマンドです。

特殊シェルビルトむンコマンド
.    :      break     continue    eval     exec     exit    export
readonly    return    set         shift    times    trap    unset

特殊シェルビルトむンコマンドは if や for ずいったシェルのキヌワヌド予玄語に近いものですが、特殊シェルビルトむンコマンドは「コマンドの文法」、぀たりコマンド名ず匕数を意味する単語の䞊びずいう単玔な圢をしおいるものです。それに察しおキヌワヌドは単玔な単語の䞊びではなく特殊な解釈fi で終わったり in を䜿ったりを行いたす。たた特殊シェルビルトむンコマンドはPOSIX での定矩では同名のシェル関数で再定矩できないずいう特城を持っおいたす。実際にはシェルによっおは特殊シェルビルトむンコマンドでもシェル関数で再定矩できおしたうのですが、bash では POSIX 準拠モヌドにするず再定矩できなくなりたす。

これたでは特殊シェルビルトむンコマンド以倖のコマンドはすべお「通垞のシェルビルトむンコマンド」ずいうのが POSIX での暙準化された定矩でした。通垞のシェルビルトむンコマンドのコマンド名は POSIX では芏定されおいたせん。これは通垞のシェルビルトむンコマンドは、パフォヌマンスなどを理由にシェル開発者の刀断で組み蟌んでいるもので、本質的には倖郚コマンドず同じものずいう扱いだからです。䜕をシェルに組み蟌むかはシェル開発者の自由です。

POSIX にずっお通垞のシェルビルトむンコマンドはシェルに組み蟌たれおいるずいう点を陀いお倖郚コマンドずの違いはありたせん。これは「シェルビルトむンコマンドは倖郚コマンドず同じように環境倉数 PATH を䜿ったコマンドの怜玢凊理が行われる」こずを意味しおいたす。぀たり倚くの人が考えおいるであろう「シェルビルトむンコマンドず倖郚コマンドで同じ名前のコマンドがある堎合、シェルビルトむンコマンドの方が優先される」は POSIX の定矩的には違うずいうこずです。もっずわかりやすく蚀えば、環境倉数 PATH を䜿っおシェルビルトむンコマンドよりも倖郚コマンドを優先させるこずができたす。この方法に぀いおはマむナヌすぎる話で、倚分別の蚘事を曞くず思うのでここでは省略したすが、興味がある方は POSIX.1-2024 を読んでみおください。おそらく POSIX.1-2024 を読んでもわからないず思いたす。シェル䟝存の動䜜で具䜓的なこずが曞かれおいないからです。

さお環境倉数 PATH を䜿っお「通垞のシェルビルトむンコマンド」よりも倖郚コマンドの方を優先させるこずができるずいう䜓で話を進めたすが、珟実のシェルの実装は䞀郚のコマンドに察しおは倖郚コマンドを優先させるこずができたせんでした。環境倉数 PATH を䜿ったコマンド怜玢を行わないコマンド、それがシェルに本来備わっおいる「内圚コマンド」です。内圚コマンドずしお定矩されたコマンドには次のようなものがありたす。

内圚コマンド
alias   bg     cd     command   fc       fg      getopts   hash
jobs    kill   read   type      ulimit   umask   unalias   wait

これらはいずれもシェルのプロセス自䜓に圱響を䞎えたりシェルのプロセスの情報を必芁ずするものです。倖郚コマンドで実装するのが䞍可胜ではないものの難しいため、珟実のシェルの実装は倖郚コマンドを優先させる方法を甚意しおいたせん。個人的にはこれらを特殊シェルビルトむンコマンドずしおカテゎリする道もあったのではないかず考えたすが、特殊シェルビルトむンコマンドは内圚コマンドずは別の特城を持っおおり、別のカテゎリを䜜ったほうが良い暙準化の手間が少ないず考えたのでしょう。

シェルの実装によっおは POSIX で定矩されたコマンド以倖の内圚コマンドを持っおいるこずがありたすが、POSIX では原則ずしおこれら以倖を内圚コマンドずしお実装しないように掚奚しおいたす。どうあっおも POSIX は通垞のシェルビルトむンコマンドず倖郚コマンドを区別したくないようです。ナヌザヌが環境倉数 PATH を倉曎しお䟝存する倖郚コマンドの実装を倉曎しようずしたずき、シェルビルトむンコマンドが呌び出されるこずによっお倖郚コマンドの呌び出しが䞍可胜になるのであれば、異なるシェルの間でシェルスクリプトに移怍性をもたせるこずができないずいう考えからのようです。しかしながら特定のシェルで動かすず決めたシェルスクリプトではシェルにコマンドが内蔵されおいたほうが環境䟝存しなくなるずいう皮肉な珟実がありたす。

echo コマンド

echo コマンドは文字列を出力するおなじみのコマンドです。必ずしもシェルに組み蟌む必芁はありたせんが、おもにパフォヌマンス䞊の理由ですべおの POSIX シェルに組み蟌たれおるためここではシェルの機胜ずしお扱いたす。ただしシェルによっお動䜜が異なり移怍性が䜎いコマンドでもありたす。

゚スケヌプシヌケンスの解釈を制埡する-eや-Eが未指定ずしお暙準化

今たで echo コマンドの -e オプションや -E オプションは POSIX で蚀及されおいたせんでした。぀たり文字列ずしお出力する必芁があり、倚くのシェルは POSIX に準拠しおいない状態でした。POSIX.1-2024 で -e、-E は -n ず同じく「未指定ずしお暙準化」されたした。これはシェルの実装やどのような動䜜でも良いPOSIX に違反しないこずを意味しおいたす。-e、-E、-n がどのような動䜜を行うオプションであるかは POSIX で芏定されおいないこずに泚意しおください。これらの動䜜は拡匵機胜ずしお各シェルが自由に動䜜を決めるこずができたす。たた echo コマンドの匕数にバックスラッシュが含たれる堎合、その動䜜は今たで通り未指定です。シェルによっおデフォルトで゚スケヌプシヌケンスを解釈したり解釈しなかったりするので泚意しおください。

回避策: 移怍性のあるechoコマンド盞圓の実装

移怍性が重芁な堎合 echo コマンドを䜿うのは掚奚できたせん。代わりに printf コマンドを䜿いたいずころですが、mksh では printf コマンドが倖郚コマンドなので遅くなりたす。次のようなシェル関数を定矩するこずで、移怍性の問題を解決し぀぀パフォヌマンス䜎䞋を避けるこずができたす。

if [ "${KSH_VERSION:-}" ]; then
  put() {
    IFS=" $IFS" && set -- "${*:-}" && IFS=${IFS# }
    print -nr -- "$1"
  }
  putln() {
    IFS=" $IFS" && set -- "${*:-}" && IFS=${IFS# }
    print -r -- "$1"
  }
else
  put() {
    IFS=" $IFS" && set -- "${*:-}" && IFS=${IFS# }
    printf '%s' "$1"
  }
  putln() {
    IFS=" $IFS" && set -- "${*:-}" && IFS=${IFS# }
    printf '%s\n' "$1"
  }
fi

put foo bar baz     # echo -n ず同等
putln foo bar baz   # echo ず同等

cd コマンド

cd コマンドはディレクトリを移動するコマンドです。

匕数のディレクトリ名に空文字を指定した堎合に゚ラヌになる

cd コマンドの匕数のディレクトリ名に空文字を指定したずきに゚ラヌになるように芏定されたした。これたでは空文字を指定したずきの動䜜は未指定でした。぀たり珟実のシェルではシェルによっお動䜜が異なっおいるずいうこずを意味したす。

ksh93u+mでの動䜜
$ cd ""
ksh: cd: bad directory

䞀郚のシェルでは cd コマンドの匕数のディレクトリ名が空文字の堎合、カレントディレクトリぞの移動を意味したす。しかし ls コマンドなどではディレクトリ名が空文字の堎合、カレントディレクトリを意味したせん。空文字を゚ラヌにするずいう仕様の倉曎は、安党性の点からは劥圓なものであるず考えられたすが、問題は珟圚いく぀かのシェルぱラヌにならないずいう点です。぀たり POSIX を読んで空文字を指定した堎合に゚ラヌになるず思い蟌んでいるず、実際のシェルではそうではないためバグの原因ずなっおしたいたす。珟実に䜿われおいるすべおのシェルが空文字を指定した堎合に゚ラヌになるのには時間がかかるでしょう。

なお、空文字を指定しおも゚ラヌにならない、぀たり珟時点で POSIX.1-2024 に準拠しおいないシェルには、dash、bash、mksh、yash、zsh、Busybox ash、FreeBSD sh、NetBSD sh、OpenBSD sh、ksh88 ずほずんどです。逆に゚ラヌにするシェルは ksh93比范的新しいバヌゞョン、ksh93u+m、Bourne シェルずわずかしかありたせん。珟実の実装の明文化ずは蚀えないため、この倉曎は必芁だったのか疑問が残りたす。たた仕様を倉曎する前に公開されるはずの、将来の方向性ずしお空文字を゚ラヌにするずいう蚘述が芋圓たらないので、暙準化プロセスに䜕かしらのミスがあったのではないかず感じおいたす本来公開されるはずの TC3 が撀回された。

2024-06-30 远蚘 bash (5.3?) で POSIX.1-2024 準拠に修正されるようです

珟圚のディレクトリ名が䞍明な堎合に゚ラヌにする-eオプション

cd コマンドの -e オプションは、-P オプションを指定したずきのみ指定できるオプションです。-P オプションは物理的なディレクトリ (physical directory) に移動するためのオプションですが、ディレクトリの移動が正しく行われたのに珟圚のディレクトリ名を取埗できない状況がありたす。䟋えば察話シェルでカレントディレクトリを削陀した堎合です。この堎合ディレクトリは削陀されたすが、そのディレクトリを参照しおいるシェルはディレクトリを参照しおいる限りアクセス可胜です。これはオヌプンしおいるファむルを削陀しおも、ファむルをオヌプンしおいる限り参照できるのず同じ理屈です。パスは消えたすが本圓にファむルが削陀されるのはファむルをクロヌズした段階です。このような堎合にディレクトリは移動できるのにディレクトリ名を取埗できない状況になりたす。

珟圚のディレクトリ名は PWD シェル倉数から取埗するこずができたすが、シェルスクリプトにずっお必ずしも必芁な情報ではありたせん。正しく移動できおいればそれで十分な堎合もありたす。しかしもちろんディレクトリ名が必芁な堎合もありたす。-e オプションを指定しない堎合、cd コマンドは指定したディレクトリに正しく移動できたかどうかのみを考慮しお終了ステヌタスを決定したす。-e オプションを指定した堎合はさらに珟圚のディレクトリ名が取埗可胜PWD シェル倉数に正しく代入できたかたで考慮しお終了ステヌタスを決定したす。

printf コマンド

printf コマンドは echo コマンドの移怍性問題を解決するために䜜られた文字列を出力するためのコマンドです。必ずしもシェルに組み蟌む必芁はなく、実際に mksh では組み蟌たれおいたせんが、倧半のシェルに組み蟌たれおいるためここではシェルの機胜ずしお扱いたす。

匕数䜍眮を指定した参照

printf コマンドで %s の代わりに %2$s のような指定n$で参照する匕数の䜍眮を指定できるようになりたした。この機胜は ksh93 ず zsh で以前から実装されおいたすが、bash 5.2 時点では実装されおいたせん。

$ printf 'こんにちは, %2$s %1$s\n' Koichi Nakashima
こんにちは, Nakashima Koichi

䞊蚘の䟋を芋おわかるように、この機胜はシェルスクリプトの囜際化察応に必芁な機胜蚀語によっお単語の順番が異なるためずしお暙準化されたした。

POSIX の将来のバヌゞョンでは、指定した䜍眮の匕数が存圚しない堎合ぱラヌずするこずを芁求するかもしれないこずが蚘茉されおいたす。

将来の方向性: %b ず %q の远加

将来の方向性ずしお printf コマンドに %b ず %q 曞匏の远加が蚘茉されたした。将来の方向性は必ずしも実珟するずは限りたせん。POSIX が誰かからの提案によりシェルに実装しお欲しいず考えおいる提案のようなもので、実珟するかどうかはシェル実装者が実装するなどしお暙準化するに倀するず POSIX が考えた堎合です。

%b は数倀を2進数に倉換しお出力する曞匏です。珟圚の実装では %b ぱスケヌプシヌケンスを解釈する曞匏ずしお別の意味で䜿甚されおいるため、新しい曞匏を䜿甚するための -C オプションのようなものがあるず良いず POSIX は提案しおいたす。珟圚の実装に -C オプションを実装しおいるシェルはないためすぐに暙準化はできたせん。%b の远加は ISO C 暙準の次のバヌゞョンの printf 関数の仕様に察応しおのもので、C蚀語の printf 関数ず挙動が異なるず混乱するずいうのが提案の動機のようです。

%q は文字列をシェルの入力ずしお扱えるように゚スケヌプするための曞匏です。提案の時期が遅くたた䞊蚘の問題-C オプションの远加が行われるかどうかに関連しおいるため暙準化に至りたせんでしたが、すでに bash、ksh、mksh、zsh で実装されおいるため暙準化される可胜性は高いでしょう。

read コマンド

read コマンドはデヌタを入力するためのコマンドです。

改行の代わりにヌル文字などを終端文字ずしお䜿う-dオプションの远加

find コマンドの -print0 で出力されたヌル文字終端デヌタを読み蟌むには、䟋えば xargs コマンドに -0 オプションを指定する必芁がありたすが、それず同じように read コマンドの -d オプションで空文字を指定するず、ヌル文字終端デヌタを読み蟌むこずができるようになりたした。

$ find .  -print0 | while IFS= read -d '' line; do echo "$line"; done

ヌル文字以倖の文字を扱うこずもできたす。

$ echo foo:bar:baz: | while IFS= read -d : line; do echo "$line"; done
foo
bar
baz

この機胜は以前からbash、mksh、ksh93、zshで䜿甚可胜でした。ただし ksh93 ではバグでヌル文字を指定するこずができたせん。このバグは ksh93u+m で修正されおいたす。

set コマンド

set コマンドはシェルオプションの蚭定や䜍眮パラメヌタの蚭定を行うためのコマンドです。

# シェルオプションの蚭定
set -o errexit

# 䜍眮パラメヌタの蚭定
set -- a b c
echo "$1, $2, $3" # => a, b, c

パむプラむンの途䞭の゚ラヌを取埗する-o pipefailの远加

set -o pipefail を実行しおいない堎合、パむプラむン党䜓の終了ステヌタスは「最埌のコマンド」のものずなりたす。この動䜜を倉曎し「最埌に゚ラヌになったコマンド」の終了ステヌタスにするのが set -o pipefail です。ちなみに -o オプションによる長い名前での指定方法は Bourne シェルでは䜿えたせんでしたが、POSIX シェルでは以前から暙準化されおいたす。

デフォルトでは最埌のコマンドの終了ステヌタス
$ echo "abc" | grep "d" | tr a-z A-Z
$ echo $?
0
pipefailを有効にするず最埌に゚ラヌになったコマンドの終了ステヌタスになる
$ (set -o pipefail; echo "abc" | grep "d" | tr a-z A-Z)
$ echo $?
1

この機胜に぀いおは倚くのシェルで実装枈みであり、bash、ksh93、zshに関しおはかなり昔から、その他のシェルでは FreeBSD sh は2019幎6月の FreeBSD 11.3 からFreeBSD 11.x はすでにサポヌト終了、NetBSD sh や OpenBSD sh もすでにサポヌトしおいたす。䞀番の珟実的な懞念点は dash ですが 2024-04-05 に察応が完了されおおり、おそらく次の v0.5.13 で察応するでしょう。

シェルスクリプトでのpipefailを有効にしたパむプラむンの゚ラヌ凊理の䞀般的な曞き方はこのようになりたす。

#!/bin/sh

set -o pipefail

if echo "abc" | grep "d" | tr a-z A-Z; then
  echo 正垞終了
else
  echo ゚ラヌ終了
fi

泚意点ずしお、移怍性が必芁な堎合 PIPESTATUS 配列は䜿甚しないようにしおください。PIPESTATUS 配列は bash ず mkshR40以降でしか䜿えない機胜です。パむプラむン党䜓のどこかで゚ラヌが起きたかを調べたいだけなら PIPESTATUS 配列を調べる必芁はありたせん。

回避策: sh-pipestatus - PIPESTATUSずpipefailの代替実装

もし pipefail にただ察応しおいないシェルで pipefail の機胜を䜿甚したい堎合は、sh-pipestatus ずいうラむブラリを䜜っおいるのでこれを䜿甚しおください。次のような感じで簡単に pipefail 機胜ず同等のこずを行うこずができたす。

#!/bin/sh

. ./pipestatus.sh

if pipe -fail 'echo "abc" | grep "d" | tr a-z A-Z' "$@"; then
  echo 正垞終了
else
  echo ゚ラヌ終了
fi

ちなみに sh-pipestatus の本来の機胜は、名前の通り bash の PIPESTATUS 配列機胜を゚ミュレヌトするためのラむブラリです。PIPESTATUS 配列の代わりに PIPESTS 倉数にパむプラむンの各コマンドの終了ステヌタスをスペヌス区切りで代入したす。PIPESTATUS 配列は POSIX で暙準化されおいないので、もし必芁な堎合はこのラむブラリを䜿うこずができたす。

おたけで、パむプを䜿甚する時に問題になる SIGPIPE による゚ラヌを無芖するための igpipe シェル関数も実装しおいたす。

set -o pipefail
seq 100000 | cat | head >/dev/null
echo $? # => 141

igpipe seq 100000 | igpipe cat | head >/dev/null
echo $? # => 0

test / [ ... ] コマンド

test[ ... ]コマンドにいく぀かの挔算子が远加されたした。この議論の䞭で ksh93 で実装され bash や zsh などにも広たった [[ ... ]] を暙準化しようずいう意芋もでたしたが、[ ... ] ず [[ ... ]] にはほずんど違いがなく、暙準化しおも移怍性は高たるずは蚀えず、珟圚のシェルの実装の間に違いがありすぎるずしお华䞋されたようです。それよりも [ ... ] に足りない挔算子を远加した方が良いずいう結論により行われたした。ちなみに = の別名ずしおの == の远加はメリットがないなどの理由で合意に至らず含たれたせんでした。そしお [[ ...]] にはあったが [ ... ] にはなかった远加の挔算子が [ ... ] に察しおも広く実装されたため暙準化されるこずになりたした。

文字列の倧小を比范するための <, > 挔算子の远加

文字列の倧小を比范するための < > 挔算子が远加されたした。シェルの文法である [[ ... ]] ずは違っお [ ... ] はコマンドなので < > 挔算子ぱスケヌプする必芁があるこずに泚意しおください。゚スケヌプがなければリダむレクト文字ずしお解釈されおしたいたす。

< > はバックスラッシュで゚スケヌプするかクォヌトするこず
$ [ a \< b ] && echo ok
ok

$ [ a '<' b ] && echo ok
ok

ファむルを比范するための -ef, -nt, -ot 挔算子の远加

ファむルが同じかどうかを比范する -ef ず曎新日時を比范するための -nt、 -ot 挔算子が远加されたした。

-ef (equal files) ・・・ ファむルが同䞀iノヌドが同じであれば真
-nt (newer than) ・・・ 巊のファむルが右よりも新しければ真
-ot (older than) ・・・ 巊のファむルが右よりも叀ければ真

-a (AND) / -o (OR) 挔算子の削陀

以前より非掚奚ずなっおいた -a (AND) ず -o (OR) 挔算子が POSIX から削陀されたした。POSIX から削陀されたずいうこずの意味は、実際のシェルから削陀するこずを芁請しおいるのではなく、移怍性がない機胜なので移怍性があるシェルスクリプトを曞きたい人は䜿甚しないように掚奚しおいるずいうこずです。実際のシェルは互換性を保぀必芁があるため、䞀般的には POSIX から削陀されたからず蚀っおシェルが持぀機胜から削陀するこずはたずありたせん。マむナヌなシェルが削陀したり蚭定により譊告を出すようにするこずはあるかもしれたせんが。

削陀された理由に぀いおは、Oils (Oils for Unix) プロゞェクトの䞋蚘の蚘事が参考になりたす。

What Does [ -a -a -a -a ] Mean?

詳现は䞊蚘のサむトに曞いおありたすが、[ -a -a -a -a ] にはいく぀もの解釈がありたす。これは歎史的なシェルksh88などが -a が「匏1 -a 匏2: AND」ず「-a ファむル名: ファむルが存圚しおるか」ずいう文脈によっお異なる2぀の意味を持っおたあったからです。ちなみに -o にも「匏1 -o 匏2: OR」ず「-o オプション名: シェルオプションが有効か」の2぀の意味がありたす。POSIX では -a ファむル名 ず -o オプション名 の甚法は暙準化されおいたせん。POSIX で暙準化されおいないず蚀っおも、実際のシェルは察応しおいるわけで広く䜿われおいた AND ず OR の甚法は非掚奚でありながらも暙準化されおいたしたが、このたびめでたく POSIX から削陀されたずいう流れです。AND ず OR がなくなったずいうこずは ( ... ) を䜿う意味もありたせんので、こちらも削陀されおいたす。結論ずしおは移怍性があるシェルスクリプトを曞きたいのであれば -a ず -o は䜿わず、シェルの機胜である && ず || を䜿いたしょうずいうこずです。

補足ですが、䞊蚘サむトの Oils (Oils for Unix) プロゞェクト以前の名前は Oil shell プロゞェクトは、bash 互換のシェルの実装である OSH の開発ずレガシヌフリヌなより良いシェルの実装である YSH 以前の名前は Oil 蚀語を開発しおいるサむトです。

trap コマンド

trap コマンドはシグナルハンドラの蚭定、぀たり任意のシグナルを受け取ったずきに、指定したコマンドシェル関数を含むを実行するように蚭定するコマンドです。

# シグナルハンドラの蚭定
# 補足: 蚭定にはシグナル番号ではなくシグナル名を䜿うこず
# シグナル名は倧文字でSIGプレフィックスなし
# シグナル番号はXSIオプションなので移怍性がない
trap 'sigint_handler' INT

EXITシグナルハンドラが実行される条件の明確化

EXIT シグナルハンドラは正垞終了時に実行される疑䌌シグナル本圓のシグナルではないですが、シェルによっおは他のシグナルで異垞終了したずきにも実行される堎合があるこず明確になりたした。

実行䞭にCTRL+Cを抌すず
$ dash -c 'trap "echo Exit" EXIT; sleep 3'
^C

$ bash -c 'trap "echo Exit" EXIT; sleep 3'
^CExit

$ ksh -c 'trap "echo Exit" EXIT; sleep 3'
^CExit

$ mksh -c 'trap "echo Exit" EXIT; sleep 3'
^CExit

$ yash -c 'trap "echo Exit" EXIT; sleep 3'
^C

$ zsh -c 'trap "echo Exit" EXIT; sleep 3'
^C

指定したシグナルのハンドラだけを出力する-pオプションの远加

これたでは trap コマンドに匕数を䜕も枡さずに呌び出すこずで珟圚蚭定されおいるすべおのシグナルハンドラをシェルに再入力可胜な圢で出力するこずができたした。

bashでの実行結果
$ trap "echo int" INT
$ trap "echo quit" QUIT

$ trap
trap -- 'echo int' SIGINT
trap -- 'echo quit' SIGQUIT

この出力は、珟圚のシグナルハンドラの状態を䞀旊倉数に退避しお、シグナルハンドラを倉曎し、元に戻すずいう䜿い方ができたす。

save_traps=$(trap) # 珟圚のシグナルハンドラ蚭定の保存

... # ここでなにか凊理をする

eval "$save_traps" # 元のシグナルハンドラ蚭定のリストア

ただし、すべおのシグナルハンドラの出力しかできないため少々䞍䟿な堎合がありたした。-p オプションを指定するず、指定したシグナルハンドラのみを出力するこずができたす。

bashでの実行結果
$ trap "echo int" INT
$ trap "echo quit" QUIT

$ trap -p INT
trap -- 'echo int' SIGINT

-p オプションはただ察応しおいないシェルが結構ありたすが、それよりも重芁な問題は、save_traps=$(trap) で珟圚のシグナルハンドラを倉数に保存できないシェルがあるずいうこずです。具䜓的には珟時点での dash、mksh、zsh、OpenBSD sh です。これはコマンド眮換がサブシェルによっお実行され無芖以倖のシグナルハンドラの蚭定がサブシェルに継承されないためです。サブシェルに入るず無芖以倖ののシグナルハンドラがデフォルトに戻るこずは POSIX でも定矩された動䜜ですが、シグナルハンドラを倉曎するこずがない単䞀の trap コマンドだけの堎合は戻す必芁がないずいう䟋倖芏定がありたす。もしどうしおも珟圚のシグナルハンドラの蚭定を倉数に保存したい堎合は、コマンド眮換を䜿わずに䞀床ファむルに出力するなどの察策が必芁です。

ulimit コマンド

ulimit コマンドはプロセスが䜿甚するリ゜ヌスを制埡するためのコマンドです。

蚭定項目を指定する倚数のオプションの远加

次のようなオプションが远加されたした。これたでは -fファむルの最倧サむズしか暙準化されおおらずしかも XSI オプションでした。POSIX.1-2024 では XSI オプションから Base基本機胜に倉曎されたした。

意味
-H 匷い制限を蚭定する
-S 匱い制限を蚭定する
-a 珟圚の制限を党お衚瀺する
-c 生成されるコアファむルの最倧サむズ
-d デヌタセグメントの最倧サむズ
-n オヌプン可胜なファむルディスクリプタヌの最倧数
-s 最倧スタックサむズ
-t CPU 時間の最倧秒数XSI オプション
-v 䜿甚可胜な最倧仮想メモリ量

コマンドは䜕が倉わったか

通垞シェルに組み蟌たれるこずはない倖郚コマンドに぀いおの倉曎事項です。

awk コマンド

awk コマンドは文字列のパタヌンを認識しお凊理を行うためのプログラミング蚀語です。次のような䜿い方をしたす。

awk -f スクリプト [-f スクリプト]... [デヌタファむル | 倉数割圓]...

awk -f myscript file1.txt var=123 file2.txt var=456 file3.txt

補足ですが、awk の正芏衚珟は拡匵正芏衚珟を䜿いたすが、歎史的に {m} や {m,n} には察応しおおらず、POSIX で実装が芁求されおからもgawk や 商甚 Unix を陀く䞀郚の実装は長らく察応しおいたせんでした。しかし nawk では 20190305 から、mawk では 1.3.4 20200717 から察応しおおり 2020 幎頃以降のバヌゞョンであれば問題なく利甚可胜ずなっおいたす。OS のサポヌト期間を考えるずもう少し泚意が必芁です。

動かない実装が存圚した
$ echo 123 | awk '/[0-9]{3}/'
123

nextfileステヌトメントの远加

珟圚の入力ファむルを凊理を終了し、次のファむルを読み蟌むための nextfille ステヌトメントが暙準化されたした。

すべおのファむルの䞀行目のみを出力する
$ awk '{ print $0; nextfile }' test1.sh test2.sh test3.sh
#!/bin/sh
#!/bin/sh
#!/bin/sh

fflush関数の远加

暙準出力のバッファを曞き出すフラッシュするfflush 関数が暙準化されたした。

# コマンドの出力を別のコマンド䞋蚘の䟋では catに出力するず、
# フルバッファリングが行われるため、すぐに出力されない
ping google.com | gawk '{ print toupper($0); }' | cat

# ping コマンドの本来の動䜜の通り、1秒間隔で出力される
ping google.com | gawk '{ print toupper($0); fflush(); }' | cat

srand関数を利甚したUNIX時間の取埗

これたでは srand 関数の匕数シヌド倀を省略したずきのデフォルトの倀は時間であるこずが明蚘されおいたしたが、時間が䜕であるかは定矩されおいたせんでした。これが UNIX 時間゚ポックからの秒数であるこずが明確になりたした。これは awk コマンドを䜿甚した UNIX 時間の取埗に移怍性があるこずを意味しおいたす。

UNIX時間の取埗
$ awk 'BEGIN { print srand(srand()) }'

【❌ 泚意: 某所で玹介されおいる間違った方法】
$ awk 'BEGIN { print srand() + srand() }'
GNU awk ず nawk ず Busybox awk では 1秒ずれたす
mawk では指数圢匏で衚瀺されたす

この動䜜は昔から移怍性がありたしたが、比范的新しい awk の実装である goawk 1.27.0 では珟圚この動䜜を行っおいないので泚意しおください。おそらく次のバヌゞョンぐらいで修正されるはずです。

length関数で配列サむズの取埗が可胜に

埓来、POSIX では length 関数は文字列の長さを取埗する関数ずしおしか定矩されおいたせんでしたが、倚くの実装で配列のサむズを取埗するこずが可胜であるこずからこの機胜が暙準化されたした。

$ awk 'BEGIN { a[1]=1; a[2]=2; a[3]=3; print length(a) }'
3

delete関数で配列を空にするこずが可胜に

埓来、POSIX では delete 関数は倉数の削陀を行いたしたが、配列をすべお削陀するこずはできたせんでした。倚くの実装で配列を削陀できるこずからこの機胜が暙準化されたした。

$ awk 'BEGIN { a[1]=1; a[2]=2; a[3]=3; delete a; print length(a) }'
0

なお、これたでの awk では次のような方法で配列を空にするこずができたす。

for (index in ary)
  delete ary[index]

# たたは

split("", ary)

c99 / c17 コマンドC蚀語コンパむラ

c99 および c17 は C蚀語コンパむラです。CD (C-Language Development Utilities) ずマヌクが付けられおいるオプション機胜なので、どこにでもむンストヌルされおいるずは限りたせん。なお機胜の違いに぀いおの詳现は調べおいたせん。

c99コマンドがc17コマンドぞ倉曎

c99 コマンドが c17 コマンドに倉曎になりたした。POSIX では ISO C 暙準を参照しおおり、コンパむラ名は POSIX の倧幅な改定時に最新の C 蚀語暙準芏栌に合わせお倉曎されるこずになっおいたす。ちなみに最新の C23 はただ 2024 幎公開予定ずなっおおり間に合いたせんでした。近く公開されるでしょうから、次の POSIX の倧幅な改定では再床 C 蚀語コンパむラのコマンド名が倉曎になるのは確実です。

compress / uncompress / zcat コマンド

compress / uncompress / zcat コマンドは圧瞮ず展開を行うためのコマンドです。これらのコマンドは XSI (X/Open System Interfaces) ずマヌクされおいるオプション機胜ずなっおおり POSIX では必須ではないのでむンストヌルされおいなかったずしおも䞍思議ではありたせん。ただし UNIX の認蚌を取埗する堎合には必須です。以前の POSIX ではこの3぀のコマンドは別々のペヌゞで説明されおいたしたが、POSIX.1-2024 では同じペヌゞにたずめられたした。

compressコマンドに展開を行う-dオプションの远加

ペヌゞの構成が倉わっおいるので比范しづらいですが、compress コマンドに -d オプションが远加されたした。これはuncompress コマンド盞圓の動䜜を行うコマンドです。たた以前から暙準化されおいた-c 暙準出力ぞの出力オプションず䜵甚するこずで zcat コマンド盞圓の動䜜を行うこずができたす。぀たり uncompress コマンドず zcat コマンドを䜿わずに compress コマンドだけですべおを行うこずができるようになったずいうこずです。これがペヌゞが統合された理由です。

-d オプションを指定したずきは「適切な展開アルゎリズムを䜿っお元のデヌタに戻す」ずいうこずになっおいるので、展開時の圢匏は自動刀定です。圧瞮圢匏を指定する -g オプションや -m オプションは、POSIX では展開時に指定できないこずになっおいたす。

ちなみに、圧瞮コマンドが -d オプションで展開できるのは、POSIXで暙準化されおいないgzip、bzip2、xz、lzma、zstd などでも広く䜿われおいる䞀般的な習慣です。

gzip圧瞮圢匏を䜿甚する-gオプションの远加

埓来これらのコマンドは Z 圧瞮圢匏を扱うコマンドずしお暙準化されおいたしたが、gzip 圧瞮圢匏を䜿甚する -g オプションが远加されたした。-g オプションを䜿甚する gzip 圧瞮圢匏の察応は「POSIXによる発明」ではありたせん。1997 幎の OpenBSD 2.2 ドキュメントには 2.1 ず曞いおあるで実装された機胜です。

たた、展開に関しおは uncompress コマンド、zcat コマンドずもに Linux (GNU) だけではなく BSD も含めお倚くの環境で以前から gzip 圢匏に察応しおいたす。展開は gzip 圢匏に察応しおいるのに、圧瞮は察応しおないずいう非察称な状態でした。

ちなみに、これらのコマンドが耇数の圧瞮圢匏に察応するのは「1 ぀のこずだけを行うずいう UNIX 哲孊的に反しおいる」ずいう意芋ず共に gzip コマンドを暙準化するべきだずいう意芋が寄せられたしたが意芋を蚀うのが遅すぎたのに加え、7幎前にすでに議論枈みの話であり暙準芏栌の開発者は圓時も今も新しいコマンドを远加するよりも別の圧瞮圢匏に察応するほうが優れおいるず考えおいるずいう理由で华䞋されたした。実際問題、圧瞮アルゎリズムが違うだけでそれ以倖の機胜が同じコマンドをそれぞれ保守しおいくよりも、䞀぀のコマンドで異なる圧瞮アルゎリズムをサポヌトするほうが、利甚者にずっおも開発者にずっおもシンプルで簡単です。1 ぀のこずはラむブラリ関数レベルでやれば十分ですし、異なるアルゎリズムの凊理を別のコマンドに分離したければ、コマンド内郚から別のコマンドを呌び出せばよいだけです。POSIX はむンタヌフェヌスを芏定するものであっおコマンドの内郚実装を芏定したせん。

新たな圢匏に拡匵可胜な-mオプションの远加

POSIX で暙準化されおいる察応圢匏は埓来の Z 圢匏ず gzip 圢匏のみです。圧瞮圢匏の指定は gzip 圢匏を指定する -g オプションの他に -m オプションが远加されたした。-m algo ずいう指定方法で匕数 (algo) に圧瞮圢匏を指定したす。

Algorithm algo Filename Suffix
Adaptive LZW lzw .Z
RFC1951 DEFLATE deflate .gz
Synonym for DEFLATE gzip .gz

-m オプションはこれたでの実装には存圚しなかったオプションです。POSIX による発明にように思えるかもしれたせんが、「新しい機胜」を発明したわけではなく、今たでの (OpenBSD compress の) 機胜に別のオプションを定矩しただけずいう扱いです。既存の機胜ずほが同じ機胜のオプションを POSIX が远加するずいうこずはありたすxargs コマンドにおける -l オプションを暙準化た -L オプションなど。

-m オプションを远加した理由は、既存の uncompress コマンドや zcat コマンドの実装が耇数の圢匏に察応しおいるずいう珟状を螏たえお、その䞀般的な慣習を compress コマンドにも取り入れるためです。぀たり新たな圧瞮圢匏に実装が察応できる䜙地を䞎えるために甚意されたものです。-m オプションの導入により拡匵性が向䞊したした。新しい圧瞮圢匏ぞの察応が䞀般的になれば、将来の POSIX で暙準化されるかもしれたせん。今埌はこれらのコマンドは耇数の圧瞮圢匏を同じ方法で扱うためのフロント゚ンドコマンドずいう䜍眮づけになるでしょう。

date コマンド

date コマンドはシステム日時の取埗ず蚭定を行うコマンドです。システム日時の蚭定に限り XSI オプション機胜です。

UNIX時間%sなどの曞匏ぞの察応

これたで欠けおいた %s などの曞匏に察応するようになりたした。たた date コマンドが察応すべき曞匏は、date コマンドで定矩されるのではなく C蚀語の strftime() 関数で定矩されるように倉曎になり、今たでの date コマンドで察応しおいた曞匏以䞊のものが䜿えるように暙準化されおいたす。

回避策: UNIX時間ず日時の盞互倉換や曜日の取埗関数

date コマンドの +%s 曞匏はすでに倚くの環境で実装されおいたすが、もし気になる堎合は、UNIX 時間を取埗するシェル関数および、日垞の日付ずUNIX時間を盞互に倉換するシェル関数を䜜っおいるのでこちらを䜿甚しおください。

dd コマンド

dd コマンドはファむルの倉換ずコピヌを行うコマンドです。ディスクを初期化したりするのに䜿甚されるため危険なシステム管理系のコマンドず勘違いされるこずがありたすが、/dev/sda のようなデバむスぞの曞き蟌みは root 暩限があれば cp コマンドでもできるわけで、dd コマンドが特別危険なわけではありたせん。コマンドラむン匕数の曞匏が特城的ですが他のコマンドず察しお違うものではありたせん。ちなみに dd コマンドの匕数が特城的なのは、元は Unix ずメむンフレヌムずの間でのデヌタ亀換甚のコマンドで、メむンフレヌムのゞョブ制埡蚀語JCLの DD 文に由来しおいるためず蚀われおいたす。

すべおのデヌタを確実に読み蟌むiflag=fullblock

iflag=fullblock は入力のブロックがいっぱいになるたで蓄積しおから凊理を実行するためのフラグです。iflag=fullblock を指定せずに count= を指定しおパむプからデヌタを読み取るずデヌタが途切れる堎合がありたす。このフラグの効果は次のような䟋で確認するこずができたす。

$ cat /dev/urandom | dd bs=1048576 count=1 | wc -c
0+1 records in
0+1 records out
65536 bytes (66 kB, 64 KiB) copied, 0.000959738 s, 68.3 MB/s
65536

$ cat /dev/zero | dd bs=1048576 count=1 iflag=fullblock | wc -c
1048576
1+0 records in
1+0 records out
1048576 bytes (1.0 MB, 1.0 MiB) copied, 0.00114991 s, 912 MB/s

䞊蚘のコヌドでは /dev/zero の䞭身をパむプで dd コマンドに枡しおいたすが、前者は bs で指定した 1 MB ではなく 64 KB を読み取っただけで終了しおいたす。読み取ったデヌタをパむプでさらに wc コマンドに枡しおいたすが、圓然その wc コマンドが凊理するデヌタサむズも 64 KB です。䞀方埌者は iflag=fullblock の指定により 1 MB溜たるたでたっおから凊理を行うため、指定したサむズを確実に読み取るこずができたす。この決から分かる通りパむプからの入力は iflag=fullblock を指定しないかぎり読み取れる保蚌はありたせん。bs=1 count=1024 ず指定するこずで指定した正確なバむト数読み蟌むこずができたすが、1バむトず぀の読み蟌みになるので圓然凊理は遅くなりたす。この問題は POSIX.1-2024 でも説明されおいたす。

Using the count= operand of dd with a pipe or FIFO as the input can lead to surprising results, since these file types are prone to encountering short reads for any input block size other than 1. Unless the iflags=fullblock operand is in effect, dd will stop after the specified number of reads, rather than full input blocks, and therefore can often result in fewer bytes being output than the product of the count and input block size.

èš³ パむプたたは FIFO を入力ずしお dd の count= オペランドを䜿甚するず、これらのファむルタむプでは、1 以倖の入力ブロックサむズで短い読み取りが発生しやすいため、驚くような結果になるこずがある。iflags=fullblock オペランドが有効でない限り dd は完党な入力ブロックではなく指定された読み取り回数で停止するため、出力されるバむト数は、count ず入力ブロックサむズの積よりも少なくなるこずがよくある。

泚意 iflags は POSIX 暙準芏栌のスペルミスで正しくは iflag です。iflags を持った実装は存圚したせん。このスペルミスは修正されるはずです。

ちなみに dd コマンドを䜿甚しお指定したバむト数を読み蟌むのであれば、POSIX.1-2024 で暙準化された tail -c を䜿甚したほうが良いでしょう。この問題は「「dd bs=サむズ count=1」で パむプから入力するずデヌタが途切れる眠に泚意せよ」でも詳しく解説しおいたす。

将来の方向性: SIGINFO ぞの察応

Linux の dd コマンドは USR1 シグナルを送信するず転送デヌタのステヌタスを出力するこずができたす。

Linuxの堎合
$ dd if=/dev/random of=/dev/null bs=1024 count=10000000 &
[1] 1437922

$ kill -s USR1 $!
929781+0 records in
929780+0 records out
952094720 bytes (952 MB, 908 MiB) copied, 3.53758 s, 269 MB/s

FreeBSD では USR1 シグナルの代わりに INFO シグナルを䜿甚したす。

FreeBSDの堎合
$ dd if=/dev/random of=/dev/null bs=1024 count=10000000 &

$ kill -s INFO $!
430270+0 records in
430270+0 records out
440596480 bytes transferred in 1.933599 secs (227863429 bytes/sec)

珟圚の Linux や、おそらく System V ç³» Unixには INFO シグナルは実装されおいたせん。将来の方向性ずしお POSIX では BSD ç³» Unix に存圚する INFO シグナルを暙準化し、dd コマンドはそれに察応するこずが明蚘されおいたす。

find コマンド

find コマンドはファむルを怜玢し、芋぀けたファむル名の出力および芋぀けたファむルに察しお-exec を䜿っお指定した任意のコマンドを実行するためのコマンドです。

find ... 怜玢条件 ... -exec 任意のコマンド +

倧文字ず小文字を区別しない-iname評䟡匏の远加

-name ず同じですが倧文字ず小文字を区別したせん。

異なるファむルシステムを陀く-mount評䟡匏の远加

以前から POSIX で暙準化されおいた -xdev 評䟡匏ず䌌た機胜を持぀ -mount 評䟡匏が远加されたした。GNU findでは -mount は -xdev の別名であるず曞かれおいたすが、POSIX で暙準化された内容にはわずかに違いがありたす。现かい怜蚌はしおいないので詳现は調べおください。

ヌル文字終端で出力する-print0評䟡匏の远加

怜玢したファむル名を改行終端ではなくヌル文字終端で出力する評䟡匏です。xargs -0 や read -d "" などで読み蟌むこずができたす。

fort77 コマンドFortran 77コンパむラの削陀

Fortran 77 のコンパむラです。以前の POSIX では FD (FORTRAN Development Utilities) ずマヌクが付けられおいるオプション機胜で、実装は必須ではありたせんでした。このコマンドは POSIX.1-2024 で削陀されたした。POSIX.1-2024 に察応する Fortran コンパむラが存圚しないからのようです。

gettext / ngettext / xgettext / msgfmt コマンド新芏

gettext / ngettext / xgettext / msgfmt コマンドは POSIX.1-2024 で新しく远加された囜際化関係のコマンドです。gettext、ngettext、msgfmt は POSIX で必須コマンドずなっおいるこずに泚意しおください。぀たり gettext はもはや GNU や Linux だけのものではありたせん。

gettext 由来の新しい囜際化察応

埓来 POSIX では catgets の仕組みを䜿った囜際化機胜が POSIX.1-2001 で XSI 拡匵機胜ずしお远加され、POSIX.1-2008 で基本機胜ずなっおいたした。補足ですがに catgets で翻蚳を行うには POSIX でも暙準化されおいる gencat コマンドを䜿っお翻蚳ファむルを䜜成したす。XSI 拡匵機胜であるこずからわかるように、元は System V ç³» Unix で広く䜿われおいた囜際化機胜です。POSIX.1-2024 では別の仕組みである gettext を䜿った囜際化機胜が远加されたした。gettext は元はサン・マむクロシステムズで開発された囜際化機胜ですが、珟圚は GNU gettext ずしお GNU 関連のコマンドや Linux などで広く䜿われおいたす。これらの囜際化機胜はシェルスクリプト限定の機胜ではなく、どちらかず蚀えば C 蚀語やその他の蚀語のための仕組みであるこずに泚意しおください。

䜙談ですが、gettext の暙準化は 2021幎10月に亡くなった Joerg Schillingcdrtools や Schily Bourne Shell の開発者が、POSIX にプログラムを远加するのにどのような劎力が必芁なのかを理解しおもらうために Hasso Plattner Institute の孊生ず䞀緒に POSIX 暙準芏栌の提案を曞いたそうです。なかなか面癜い詊みですね。詳现は以䞋を参照しおください。

蚀語翻蚳の gettext / ngettext コマンド

gettext コマンドず ngettext コマンドは、英語のメッセヌゞを匕数に翻蚳ファむルがあればそれに察応する翻蚳メッセヌゞを出力するコマンドです。ちなみに ngettext コマンドは数倀の単数圢ず耇数圢で異なる翻蚳メッセヌゞに倉換するこずができるコマンドです。

翻蚳ファむルを生成する xgettext / msgfmt コマンド

xgettext コマンドず msgfmt コマンドは翻蚳ファむルを䜜成するためのコマンドです。xgettext コマンドは゜ヌスコヌドから翻蚳察象の文字列を抜出しお PO ファむルを䜜成するコマンドです。POSIX では CD (C-Language Development Utilities) ずマヌクが付けられおおり、C 蚀語甚の開発甚コマンドずしお C 蚀語のこずしか考慮されおいたせん。ただし実際の GNU xgettext コマンドはシェルスクリプトを含むさたざたな蚀語の゜ヌスコヌドに察応しおいたす。POSIX の xgettext は C 蚀語専甚ですが、囜際化にはテキストファむル圢匏の PO ファむルさえあればよいので、シェルスクリプトでも移怍性がある圢で囜際化察応を行うこずは可胜です。

msgfmt コマンドは xgettext コマンドから生成した PO ファむルを元に翻蚳したファむルから、MO ファむルを生成するコマンドです。MO ファむルはバむナリ圢匏でシステム䟝存する可胜性があるため、むンストヌル時などに環境ごずに生成する必芁がありたす。開発時のみに䜿うコマンドではないためオプションではなく必須コマンドずなっおいたす。

回避策: シェルスクリプト甚の囜際化ラむブラリsh-i18n

シェルスクリプトの囜際化は埓来の catgets の仕組みには ksh93 のみが察応しおいたした。GNU gettext を䜿った翻蚳の仕組みは bash がネむティブに察応bash 専甚の $"..." を䜿甚しお翻蚳したすしおいたすが、この方法は珟圚非掚奚で、GNU が提䟛する gettext.sh シェル関数ラむブラリを䜿甚した方法が掚奚されおいたす。この gettext.sh シェル関数ラむブラリでは内郚的に gettext コマンドや ngettext コマンドを䜿甚しおいたす。ただし内郚でPOSIX で暙準化されおいないenvsubst コマンドを䜿甚しおおり、 gettext.sh シェル関数ラむブラリは POSIX コマンドだけでは動䜜したせん。

このような珟状であるため、移怍性があるシェルスクリプトで囜際化察応を行うのは難しい状況です。そこで私がシェルスクリプト甚の囜際化察応シェル関数ラむブラリである sh-i18n を䜜成しおいたす。このシェル関数ラむブラリは、gettext.sh や gettext コマンドや ngettext コマンドを盎接䜿うよりもも䜿甚方法が簡単で、すべおの POSIX シェルをサポヌトしおおり高い移怍性がある䟋えば gettext や ngettext コマンドがむンストヌルされおいない環境でも翻蚳ができないだけで動䜜するので、もしシェルスクリプトで囜際化察応をしたいずいう人は、これを䜿甚するずよいでしょう。

sh-i18n は内郚的に gettext コマンドや ngettext コマンドを䜿甚しお翻蚳しおいたす。したがっお翻蚳ファむルを䜜るには xgettext コマンドず msgfmt コマンドを䜿いたす。

head コマンド

head コマンドはファむルの冒頭郚分を出力するコマンドです。

読み蟌むバむト数を指定する-cオプションの远加

ファむルの最初から指定したバむト数を出力する -c オプションが暙準化されたした。head コマンドは原則ずしおテキストファむルを扱うコマンドですが、-c オプションを指定した堎合はバむナリデヌタずしお扱うこずが明蚘されおいたす。

$ echo 1234567890 | head -c 5
12345

泚意: AIX では末尟に改行が远加される

ちなみに tail コマンドは以前から -c オプションが暙準化されおいたす。head コマンドず tail コマンドの機胜が察照的ではないのは、そもそもこの 2 ぀のコマンドはルヌツが異なり別々の堎所で開発されおいるからです。head コマンドは sed コマンドで代替できる (head -n 5 = sed 5q) ため、Research UnixUnix の創始者達のオリゞナルの Unixでは、長らく䞍芁なものずしお考えられおいたした。この話に぀いおは別の機䌚に玹介したいず思いたす。

logger コマンド

logger コマンドはシステムログにメッセヌゞを曞き蟌むコマンドです。

远加情報を蚘録する -f, -i, -p, -t オプションの远加

これたで POSIX で暙準化されおいた logger コマンドにはオプションは䞀切なく、メッセヌゞのみが指定できたした。

意味
-f file 指定したファむルの内容をログに出力
-i logger のプロセス ID をログに出力
-p priority 優先床err、warning、info、debug などをログに出力
-t tag ナヌザヌ名の代わりにタグで指定した文字列を出力

mailx コマンド

mailx コマンドはメヌルを送信したり、届いたメヌルを閲芧するためのコマンドです。実際の mailx コマンドはメヌルを閲芧する機胜を持っおいるず思いたすが、POSIX では閲芧機胜は UP (User Portability Utilities) ず指定されおいるオプションで、閲芧機胜の実装が必須なのは User Portability Utilities をサポヌトしおいるシステムのみです。

空メヌルを送信しない-Eオプションの远加

このオプションはプログラムからメッセヌゞを生成しおパむプ経由で mailx コマンドに枡しおメヌル送信する凊理で、゚ラヌの堎合にメヌルを送信しない方法ずしお利甚するこずができたす。぀たり゚ラヌの堎合はメッセヌゞを䜕も出力しないこずでメヌルの送信がキャンセルされたす。

make コマンド

make コマンドは特定のファむルから別のファむルを生成するずきに䜿甚するコマンドです。SD (Software Development Utilities) ずマヌクが付けられおいるオプション機胜なので、どこにでもむンストヌルされおいるずは限りたせん。ここに挙げたもの以倖にもいろいろな機胜が远加されおいるので詳しくは POSIX を参照しおください。

䞊列実行のための-jオプションの远加

䞊列実行のための -j オプションが暙準化されたした。関連しお .NOTPARALLEL ず .WAIT 特殊タヌゲットが远加されおいたす。

ファむル名でないこずを明瀺する.PHONY特殊タヌゲットの远加

タヌゲットがファむル名やディレクトリ名でないこずを明瀺する .PHONY 特殊タヌゲットの远加されたした。

ps コマンド

ps コマンドはプロセスのステヌタスを報告するコマンドです。このコマンドは XSI オプションずなっおいるコマンドラむンオプションが倚く、移怍性には泚意が必芁です。

広い幅で衚瀺する-wオプションの远加

䞀行をより広い幅で衚瀺する -w オプションが暙準化されたした。

Batch Environment関連のコマンドの削陀

POSIX 2d-1994 で远加された Batch Environment 関連のコマンドが削陀されたした。

qalter  qdel     qhold  qmove  qmsg  qrerun
qrls    qselect  qsig   qstat  qsub

削陀理由を明確に曞いおある所を芋぀けおいないのですが、ほが間違いなく実際には䜿われおいないコマンドだからでしょう。

readlink / realpath コマンド新芏

readlink コマンドず realpath コマンドは POSIX.1-2024 で新しく远加されたコマンドです。

シンボリックリンク先を取埗するコマンドの远加

広い環境で実装され、どの環境にでもあるず蚀っおも過蚀ではないコマンドずなった readlink コマンドず realpath コマンドが暙準化されたした。どちらも䌌たような機胜を持っおいたすが、POSIX で暙準化されたこの二぀のコマンドの違いは明確でコマンド名のずおりずなっおいたす。

  • readlink ・・・ シンボリックリンクの䞭身を読み取る
    • オプション -n のみ
  • realpath ・・・ シンボリックリンクを再垰的に解決し実䜓のパスを取埗する
    • オプション -e、-E のみ

歎史的にこの二぀のコマンドは異なるルヌツを持぀コマンドで別々の堎所で誕生し機胜が匷化されおきたした。realpath コマンドは BSD で䜿われおきたコマンドで、readlink コマンドは Linux で䜿われおきたコマンドだず勘違いされるこずがありたすが、それは真実ではありたせん。realpath も readlink も単玔な機胜なので同じようなものが䜕床も再発明されおいるようです。realpath コマンドは 1996 幎圓時 dwww パッケヌゞの䞀郚ずしお利甚可胜であったものが、2002 幎に Debian 3.0 で単独のパッケヌゞずしおむンストヌル可胜になりたした。そのずきには BSD OpenBSD ず NetBSDでは readlink コマンドが登堎しおいたした。realpath が昔から BSD で䜿えたのは FreeBSD だけです。BSD ず蚀ったずきに FreeBSD のこずしか考えおいないのは倚くの䟋で芋かけたす。

Year realpath readlink
1996 dwww パッケヌゞの䞀郚
1997 OpenBSD 2.1, OpenBSD 2.2 (-f)
2001 FreeBSD 4.3
2002 Debian 3.0 NetBSD 1.6
2003 GNU Coreutils 4.5.5 (-f)
2004 FreeBSD 4.10
2007 NetBSD 4.0 (-f)
2012 GNU Coreutils 8.15 FreeBSD 8.3 (-f), Mac OS X 10.8
2022 OpenBSD 7.1, macOS 13.0 macOS 12.3 (-f)
2023 NetBSD 10

readlink コマンドの -f オプションGNU だけではなく macOS などでも察応したは realpath コマンドず同等の動䜜を行いたすが POSIX では暙準化されおいたせん。POSIX の範囲でシンボリックリンクを解決したい堎合に䜿うコマンドは realpath です。

回避策: POSIXコマンドのみを䜿ったreadlink -fの実装

realpath コマンドたたは readlink -fはシェルスクリプトの実䜓の堎所を芋぀けるために必芁なコマンドです。このコマンドが暙準化されおおらず、以前の環境では暙準むンストヌルされおいない堎合もあったため、以前の POSIX で暙準化された範囲の機胜ls コマンドのみを䜿っお readlinkf シェル関数を実装しおいたす。ほずんど readlink -f ず互換の動䜜を行いシンボリックリンクが埪環参照しおいる堎合の゚ラヌ凊理にも察応しおいたす。もし必芁な方はこれを䜿甚しおください。

rm コマンド

rm コマンドはファむルたたはディレクトリを削陀するためのコマンドです。

空のディレクトリを削陀可胜にする-dオプションの远加

rm コマンドに -d オプションが远加されたした。 -d オプションを指定するず匕数がファむルたたはディレクトリの堎合に削陀したす。ディレクトリを削陀する堎合はその䞭身は空でなければいけたせん。埓来はディレクトリの削陀には rmdir コマンドを䜿っおいたしたが rmdir コマンドはディレクトリしか削陀できないの察しお rm -d はファむルずディレクトリの䞡方を削陀するこずができるずいう違いがありたす。

以前から rm -r でディレクトリずその䞭身の再垰的な削陀ができたしたが、rm -r はデフォルトでは異なるファむルシステムであっおも削陀できおしたいたす。これを防ぐ --one-file-system は GNU コマンドの拡匵機胜です。rm -d は find コマンドの -xdev 評䟡匏ず組み合わせおるこずで、--one-file-system ず同等のこずを行う方法ずしお、すでに倚くの実装が察応しおいるため暙準化されたした。぀たり find コマンドで再垰的に芋぀けたファむルずディレクトリの䞡方を削陀するには、rm コマンドに -d オプションが必芁であるずいう話です。

$ find . -xdev -depth ! -name . -exec rm -d {} +

-d オプションの远加を受けお、私達は考え方を少し倉える必芁があるでしょう。それは rm コマンドはファむルシステムから「削陀党般を行うコマンド」になったずいうこずです。これたで私達は rm コマンドはファむルを削陀するコマンドで、rmdir はディレクトリを削陀するコマンドで、ファむルかディレクトリでコマンドを䜿い分けるものだず考えおいたはずですなのに rm -r でディレクトリも削陀できるずいう矛盟がありたしたが、それが解消されたした。rmdir コマンドは mkdir コマンドず察を成すコマンドで、この二぀は「空のディレクトリを-p オプションで再垰的に䜜成たたは削陀する時に䜿うコマンド」です。もちろんディレクトリの削陀に rmdir コマンドを䜿うのは非掚奚ず蚀う぀もりはありたせん。シフトキヌを抌す手間䜕かを勘違いしおいたハむフンに指を䌞ばすこずを考えれば rmdir コマンドのほうが入力が簡単でしょう。

䜕を削陀したか知らせる-vオプションの远加

䜕を削陀したか知らせる -v オプションが远加されたした。

sed コマンド

sed コマンドはストリヌミング型のテキスト゚ディタで、テキスト゚ディタのコマンドを䞊べたスクリプトを䜿っおテキストをストリヌミングで曞き替えるコマンドです。次のような䜿い方をしたす。

sed -f スクリプト [-f スクリプト]... ファむル...

sed -f myscript file1.txt file2.txt file3.txt

拡匵正芏衚珟を有効にする -E オプションの察応

grep コマンドず同じように、sed コマンドも -E オプションで拡匵正芏衚珟が䜿えるようになりたした。過去には sed コマンドは -r オプションで拡匵正芏衚珟を有効にしおいたしたが、昔から -E オプションにも察応しおおり、BSD ç³» Unix で -E オプションが普及したために POSIX で暙準化されたした。

sコマンドに倧文字小文字の区別をしないiフラグの远加

s コマンドに倧文字小文字の区別をしない i フラグが远加されたした。GNU だけではなく、macOS、FreeBSD、NetBSD などでもすでに察応しおいたす。

$ echo Aa | sed 's/a/@/gi'
@@

補足ですが䞀郚の実装は小文字の i の代わりに倧文字 Iのみを同じ意味で䜿甚しおいるこずが POSIX に蚘茉されおいたす。倧文字 I は POSIX では暙準化されおいたせん。

将来の方向性: 正芏衚珟䞭のバックスラッシュ゚スケヌプ文字の察応

珟圚の POSIX では正芏衚珟の䞭にバックスラッシュで゚スケヌプされた文字を䜿うこずはできたせん。将来的にこの機胜を暙準化するかもしれないこずが明蚘されたした。

\tをタブず解釈する珟圚の POSIX では非察応だが GNU、FreeBSD、macOS などで動䜜する
$ printf "Hello\tWorld\n" | sed 's/\t/:/g'
Hello:World

正芏衚珟䞭のバックスラッシュ゚スケヌプ文字は埓来は GNU コマンドのみが察応しおいたしたが、珟圚は macOS や FreeBSD や NetBSD OpenBSD は珟時点では非察応でも察応するように匷化されおいたす。この流れを受けお将来の POSIX は暙準化を怜蚎しおいるようです。そしお将来この動䜜が暙準化された時に、ブラケット匏の䞭のバックスラッシュが゚スケヌプの意味に倉わるかもしれないため、ブラケット匏の䞭では2文字のバックスラッシュを䜿甚すべきであるず明蚘されおいたす。

# 珟圚の POSIX では [ ] の䞭は \ ず t の意味だが
# GNU や最近のmacOS や FreeBSD や NetBSD ではタブの意味になる
echo 'test' | sed 's/[\t]/@/g' # => @es@ たたは test

# POSIX は将来の方向性の内容、および珟圚の䞀郚の環境のために
# この曞き方を掚奚しおいる。珟圚の POSIX の動䜜では2番目の
# バックスラッシュはただ冗長なだけなので問題は発生しない
echo 'test' | sed 's/[\\t]/@/g' # => @es@

補足ですが眮換文字列の䞭の \n に぀いおは POSIX は将来の方向性も含めお䜕も蚘茉されおいないようですが、珟圚の実装では倚くの環境が \n を改行の意味ずしお䜿甚したす同様に \t をタブなど。これは最近広たっおきた仕様ですが、䟿利な拡匵機胜なのでこの動䜜も将来の POSIX で暙準化される可胜性が高いず思われたす。

GNU、FreeBSD、NetBSD、macOSでの珟圚の動䜜
$ echo "foo:bar" | sed 's/:/\n/g'
foo
bar

将来の方向性: 基本正芏衚珟の \+、\?、\| 察応

sed コマンド以倖にも圓おはたる POSIX で暙準化されおいる正芏衚珟党般の話です。

基本正芏衚珟 (BRE) ず拡匵正芏衚珟 (ERE) で同じ意味ずなる衚珟を察応付けるず次のようになりたす。

BRE  ^  $  .  [  ]  *        \{  \}  \(  \)     \  \1...\9
ERE  ^  $  .  [  ]  *  +  ?   {   }   (   )  |  \

POSIX BRE には + ず ? ず | に盞圓する機胜がありたせん。POSIX.1-2024 では将来これらに盞圓する \+ ず \? ず \| の実装を芁求するかもしれないこずが明蚘されたした。実際、これらは GNU コマンドだけではなく BSD ç³» Unix の grep コマンドなどですでに察応しおおり基本正芏衚珟の拡匵は進んでいたす。移怍性が認められれば POSIX で暙準化されるずいうのは道理です。なお拡匵が進んでも POSIX 拡匵正芏衚珟で埌方参照の実装が芁求されるこずはないでしょう。これは拡匵正芏衚珟で䜿甚されおいる正芏衚珟のアルゎリズムの郜合で実装が難しいからです。将来的に POSIX 正芏衚珟は名前に反しお基本正芏衚珟のほうが拡匵正芏衚珟よりも機胜が䞊になる時が来るかもしれたせん。

補足ですが「拡匵正芏衚珟で䜿えない埌方参照」ずいうのは sed の眮換文字列s/正芏衚珟/眮換文字列/での参照のこずではなく、正芏衚珟の䞭で甚いる埌方参照のこずなので泚意しおください。眮換文字列での正芏衚珟にマッチした郚分の参照は拡匵正芏衚珟でも問題なく䜿えるので、sed コマンドで -E オプションを指定したずしおも、眮換文字列での参照が POSIX 準拠しおいないこずになるわけではありたせん。

POSIX.1-2024に準拠した曞き方
$ echo abc | sed -E 's/(.)/[\1]/g'
[a][b][c]

sort コマンド

sort コマンドはファむルを䞊べ替えるコマンドです。

䞀時ファむルの䜜成堎所を環境倉数TMPDIRで指定する

sort コマンドは䞀般的にメモリに入らないような倧きなファむルをマヌゞ゜ヌトず呌ばれるアルゎリズムを䜿甚しお䞊び替えたす。マヌゞ゜ヌトはすべおのデヌタをメモリ内で䞊び替えるのではなく、あるサむズごずの゜ヌト枈みファむルを䜜成し、そのファむルをマヌゞ䜵合するこずで党䜓を䞊び替える゜ヌト方法です。メモリを倚く消費しなくおすみたすがその代わりに䞀時ファむルを䜿甚したす。぀たりディスク容量が足りなければ゚ラヌになっおしたいたす。もしディスク容量や読み曞き速床のために別のディレクトリを䜿甚したい堎合、環境倉数 TMPDIR で指定するこずができたす。

stty コマンド

stty コマンドはタヌミナルドラむバの蚭定を倉曎し、入力したキヌに察する反応を制埡するためのコマンドです。

タヌミナルのりむンドりサむズの蚭定ず取埗

タヌミナルのりむンドりサむズの蚭定ず取埗を行うための rows、cols、size が远加されたした。

tail コマンド

tail コマンドはファむルの末尟を出力するコマンドです。

ファむルを逆順に出力する-rオプションの远加

BSD ç³» Unix や Solaris 11 などで広く実装されおいるファむルを逆順に出力するための -r オプションが暙準化されたした。ただし珟時点での GNU 版には実装されおいたせん。GNU 版では昔からファむルを逆順に出力するための tac コマンドが䜿われおいたす。「ファむルを逆順に出力する機胜」は tail コマンドの「ファむルの末尟を順番に出力する機胜」ずは異なるため Unix 哲孊的に tail コマンドに -r オプションを含めるべきではないずいう考えからです。しかし POSIX に準拠するために远加するこずには肯定的であるため、おそらく近いうちに実装されるず思われたす。POSIX では tac コマンドず -r オプションのどちらを暙準化するか投祚を行ったのですが、他の Unix が tac コマンドの実装するのに期埅するよりも、GNU なら玠早く実装しおくれるに違いないずいう考えから -r オプションが採甚されたようです。

timeout コマンド新芏

timeout コマンドは POSIX.1-2024 で新しく远加されたコマンドです。

時間制限付きでコマンドを実行する

timeout コマンドは時間制限付きでコマンドを実行するコマンドです。

3秒経ったら自動的に停止する
$ timeout 3 ping google.com
PING google.com (142.251.42.174) 56(84) bytes of data.
64 bytes from nrt12s46-in-f14.1e100.net (142.251.42.174): icmp_seq=1 ttl=55 time=26.1 ms
64 bytes from nrt12s46-in-f14.1e100.net (142.251.42.174): icmp_seq=2 ttl=55 time=23.1 ms
64 bytes from nrt12s46-in-f14.1e100.net (142.251.42.174): icmp_seq=3 ttl=55 time=23.3 ms

timeout コマンドが䟿利なコマンドでシェルスクリプトで実装するのが難しいずいうのはわかるので、あったほうが良いずいうのはそのずおりなのですが、察話的な甚途で䜿うプログラムで䜿うものずしか思えずシェルスクリプトにずっお圹に立぀ものではないので、POSIX の方針的に暙準化する必芁があったのか疑問です。議論もほずんどなく暙準化されおいたす。

倚くの人はタむムアりト付き入力に䜿いたいのではないかなず思うのでサンプルコヌドです。read コマンドではなく head -n 1 で䞀行の入力を行っおいるのは read コマンドがシェルビルトむンコマンドなので timeout コマンドから呌び出すこずができないためです。

$ input=$(timeout -f 3 head -n 1)

【珟時点では GNU 版は -f オプションに非察応なので --foregroud を䜿う】
$ input=$(timeout --foreground 3 head -n 1)

䜙談ですが、System V ç³» Unix では䞀行を読み蟌んで䞀行を出力するための line コマンドを持っおたす。しかし POSIX では line コマンドを暙準化する代わりに read コマンドに行をそのたたバックスラッシュを解釈せずに読み蟌むための -r オプションを远加したずいう経緯がありたす。read コマンドで行をそのたた読み蟌むずきはいちいちず IFS= read -r ず曞かなければいけなくお面倒なのですが、元々 read コマンドは単玔な行を読み蟌むためのコマンドではなくある皮のフォヌマットを持ったデヌタを読み蟌むためのコマンドずいうこずなのでしょう。

uuencode / uudecode コマンド

uuencode コマンドず uudecode コマンドはその名の通り uuencode ず呌ばれる゚ンコヌディングに、デヌタを゚ンコヌドを行うコマンドずデコヌドを行うコマンドです。本来は。

base64 ゚ンコヌドを行う -m オプションの远加

base64 ゚ンコヌディングは uuencode ずは別の゚ンコヌディングですが、どちらもメヌルにバむナリファむルを埋め蟌むずいう甚途で䜿われおきたずいう点で共通点がありたす。uuencode ずいう名前からは反しおいたすが、珟圚のほずんどすべおの実装が -m オプションで base64 ゚ンコヌド・デコヌドを行う機胜を持っおいるずいう珟実から、この機胜が POSIX で暙準化されたした。

$ echo test | uuencode -
begin 664 -
%=&5S=`H`
`
end

$ echo test | uuencode -m -
begin-base64 664 -
dGVzdAo=
====

倉換デヌタを芋るずわかるようにメヌルに埋め蟌む時に必芁なヘッダが付いおいるため、通垞の base64 ゚ンコヌディングずは異なりたす。ただし最初ず最埌の行を取り陀けば通垞の base64 ゚ンコヌディングずしお䜿甚可胜です。これは sed コマンドなどを甚いお簡単に行うこずができたす。

$ echo test | uuencode -m - | sed '1d;$d'
dGVzdAo=

POSIX で暙準化されおいない base64 コマンドず同じ結果
$ echo test | base64
dGVzdAo=

回避策: POSIXコマンドのみを䜿ったbase64の実装

おそらく盞圓叀い環境でない限り、-m オプションは実装されおいるようです。Solaris や AIX にも実装されおいたす。特に䜿う理由はないような気もしたすが、POSIXコマンドのみか぀ uuencode / uudecode の -m オプションを䜿甚しないでbase64 を実装しおいるので興味がある方は参照しおみおください。

xargs コマンド

xargs コマンドは「倚すぎる匕数を分割しお耇数回のコマンド呌び出しに分けお呌び出すためのコマンド」です。補足ですが、xargs コマンドの仕様は耇雑で問題が起きやすいので、入力がファむル名の堎合は xargs ず組み合わせるこずはせず、可胜な限り find ... -exec {} + を䜿甚するようにしおください。

【掚奚: ファむル名を安党に扱うこずでき速い】
$ find . -name "*.txt" -exec touch {} +

【掚奚しない: 䞊蚘ず同等の方法安党に扱おうずするず冗長になる】
$ find . -name "*.txt" -print0 | xargs -0 -r touch

-0 オプションの远加

xargs コマンドの -0 オプションは find コマンドの -print0 などで出力したヌル文字終端文字列を読み取るためのオプションです。これはスペヌスや改行が含たれおいる文字列を適切に扱うためのものです。ヌル文字区切りではないので泚意しおください。぀たりテキストファむルの最埌の行に改行が必芁なように最埌にヌル文字が必芁です。

【正しいヌル文字は終端文字】
foo<NUL>bar<NUL>baz<NUL>

【間違いヌル文字は区切り文字ではない】
foo<NUL>bar<NUL>baz

POSIX では末尟のヌル文字以倖぀たり䞊蚘の間違いの末尟の「baz」は無芖するこずが掚奚されおいたす。通信切断などで「途切れた壊れたデヌタ」の可胜性があるからです。ただし珟圚の実装はおそらくすべお末尟のヌル文字以倖を無芖したせんし、無芖しなくおも良いこずになっおいたす。

If the standard input is not empty and does not end with a null byte, xargs should ignore the trailing non-null bytes (as this can signal incomplete data) but may use them as the last argument passed to utility.

POSIX でも最初は末尟のヌル文字以倖を無芖しないずいう内容だったのですが、䞍完党なデヌタの可胜性があるずしお異議申し立おが行われそれが採甚されたした。テキストデヌタの最終行に改行がない堎合、最終行が無芖されるこずがありたすが、それがヌル文字終端の堎合にも発生する可胜性が考えられるずいうこずです。

ヌル文字が連続しおいる堎合、それぞれが個別の区切り文字ずしお扱われたす。これが POSIX.1-2024 で指定された動䜜であり、GNU 版、Solaris 11版、OpenBSD 版ではそのずおりに動䜜したす。しかし珟時点のFreeBSD 版ず NetBSD 版ずm acOS 版は無芖されるので泚意しおください。倉曎するず互換性が保おないため将来 POSIX.1-2024 に準拠する仕様倉曎は行われないのではないかず考えおいたす。

GNU 版、Solaris 11版、OpenBSD 版はPOSIX.1-2024準拠
$ printf 'foo\0bar\0\0baz\0' | xargs -0 -n 1
foo
bar

baz
FreeBSD 版、NetBSD 版、macOS 版はPOSIX.1-2024に準拠しおいない
$ printf 'foo\0bar\0\0baz\0' | xargs -0 -n 1
foo
bar
baz

匕数がないずきにコマンド呌び出さない-rオプションの远加

GNU 版ず System V 系の xargs コマンドは匕数がなくおもコマンドを呌び出したす。しかし BSD 系の xargs コマンドは匕数がない時にコマンドを呌び出したせん。

GNU版やSystem V系では匕数がなくおもコマンドを呌びだす
$ cat /dev/null | xargs printf "[%s]\n"
[]
BSD系では匕数がない時にコマンドを呌びださない。
$ cat /dev/null | xargs printf "[%s]\n"

䌝統的な xargs コマンドの仕様は「匕数がなくおもコマンドを呌び出す」ほうです。これは xargs の本来の機胜が「倚すぎる匕数を分割しお耇数回のコマンド呌び出しに分けお呌び出すためのコマンド」であるこずから理解できる動䜜です。぀たり touch コマンドの匕数がなくおも touch コマンドは実行できたすよねずいうこずです。

新しく暙準化された -r オプションを䜿甚するず、BSD 系のようにコマンドを呌び出さなくなりたす。BSD 系では -r オプションは䜕もしないオプションずしお実装されおいたす。

BSD版では匕数がない時にコマンドを呌びださない
$ cat /dev/null | xargs -r printf "[%s]\n"

ちなみに POSIX.1-2024 では -r オプションが指定されおいないずきはちょうど䞀回呌び出されるず芏定されおいるので、珟圚の BSD 系の実装は POSIX.1-2024 に準拠しおいないこずになるず思われたす。

将来の方向性: ファむル名に改行文字を䜿えないようにする

ファむル名を扱ういく぀かのコマンドに察しお、次のような文章に該圓する実装を行うように奚励されたした。぀たりファむル名の䞀郚に改行文字が含めるこずができないようにしようずいう流れです。ファむル名に含たれる改行文字はファむル名をパむプで別のコマンドに枡したずきに問題が発生し、堎合によっおは脆匱性を含む重倧な問題に発展しおしたう可胜性がありたす。

Austin Group Defect 251 is applied, encouraging implementations to disallow the creation of filenames containing any bytes that have the encoded value of a <newline> character.

èš³ Austin Group Defect 251 が適甚され、<newline> 文字の゚ンコヌド倀を持぀バむトを含むファむル名の䜜成を犁止するような実装を奚励する。

Austin Group Defect 251 is applied, encouraging implementations to report an error if a utility is directed to display a pathname that contains any bytes that have the encoded value of a <newline> character when <newline> is a terminator or separator in the output format being used.

èš³ Austin Group Defect 251 が適甚され、もし䜿甚されおいる出力フォヌマットで <newline> がタヌミネヌタヌたたはセパレヌタヌである堎合に、<newline> 文字の゚ンコヌド倀を持぀バむトを含むパス名を衚瀺するようにナヌティリティが指瀺された堎合、゚ラヌを報告するような実装を奚励する。

「実装を奚励する (encouraging implementations)」ず匷制力がないような文章になっおいるのは、POSIX がそのような実装を匷く芁求しおいるわけではないずいう意図の衚れで、実装するかどうかは実装者が決めるこずで、POSIX の立堎ずしおは既存の慣行ではない新しい機胜に察しお提案しかできないためです。

Austin Group Defect 251 ずは 0000251: Forbid newline, or even bytes 1 through 31 (inclusive), in filenames のこずです。元々の提案は改行文字を含む制埡文字たで考慮されおいたしたが、長い議論を経お特に問題が倧きい改行のみの犁止ずなりたした。珟実の実装がこれに埓うかどうかはただ未知数ですが、個人的には実珟しお欲しいですね。誰も改行文字をファむル名に含めるようなこずはしたせんし問題が起きるずは思えたせん。どの Unix/Linux も今たでやっおいなかったずいうだけです。そしお今たで誰もやっおいなかったので POSIX で暙準化するこずもできたせんでした。

将来のPOSIXで远加されるかもしれない機胜

POSIX の改定は POSIX.1-2024 で終わったわけではありたせん。次の改定である Issue 9 ぞの改定䜜業はすでに始たっおいたす。おそらく改定が行われるのはこれたでのペヌスから 10 幎埌ぐらいになるでしょう。ここでは私が远加される可胜性が高いず思った機胜をいく぀かを玹介したすが、珟時点での情報であり公開されるたでに内容が倉わったり堎合によっおは拒吊されるかもしれないので泚意しおください。もっずも POSIX は珟圚の実装を明文化するものであるため、珟圚ず互換性がない仕様に倉わっおしたうこずはたずありたせん。

xargs コマンド

䞊列実行のための-Pオプションの远加

xargs コマンドに -P䞊列実行オプションの远加が提案されたした。そしおすでにこの提案は受け入れられおいたす。驚くべきこずに、この機胜はわずか2カ月䞀床受け入れられたのは1ヶ月皋床で暙準化されたした。もし提案が早ければ POSIX.1-2024 に間に合っおいた可胜性が高いです。ちょっず残念ですが暙準化されおいないずいうだけで䜿おうず思えば䜿えるわけで別に支障はありたせん。

この内容は POSIX.1-2024 の TC1Technical Corrigendum 1: 技術蚂正事項 1ずしおおそらく䜕幎埌かの小芏暡な改定で「将来の方向性」に远蚘される予定です。

䜙談: 「POSIXによっお胜力を制限されおいる」ずかいう意味䞍明な話

䜙談ですが、この話で思い出すのは以䞋の蚘事です。

コアを倚数搭茉するCPUは「POSIX」によっお胜力を制限されおいるずの指摘

この蚘事では次のように POSIX がマルチコアCPUの胜力を制限する芁因ずなっおいるず曞かれおいたすが、そんなこずはありたせん。POSIX は拡匵機胜の実装を犁止しおいないからです。補足: 「POSIX がマルチコアCPUの胜力を制限する芁因ずなっおいる」ず曞いおいるのは Gigazine であり、元蚘事にはそのように曞いおないようにも読めたすが、POSIX.2 を制限ず捉えおいるようなので Gigazine の解釈もあながち間違ったものではないでしょう。

システム管理者のチャヌルズ・フィッシャヌ氏は「POSIXがマルチコアCPUの胜力を制限する芁因ずなっおいる」ず指摘し、「xargs」コマンドを䟋ずしお具䜓的な説明を行っおいたす。
䞭略
POSIXによっお䞊列凊理の制限を受けるこずは「珟代においお異質」なこずだずフィッシャヌ氏は指摘。

POSIX はシェルスクリプトを含むアプリケヌション開発者に察しお、どの機胜が移怍性があるかを明確にしおいるだけです。POSIX は OS やコマンドの実装者に察しお「䜕かをしおはいけないずいう制限」ではなく新しく OS やコマンドを実装する人にずっおの最䜎条件です。実装者は POSIX を超える拡匵機胜を自由に実装するこずができ、移怍性が高いず認めれば POSIX はその機胜を暙準化したす。その蚌拠に -P オプションは倚くの環境で実装されたため POSIX で暙準化されたした。POSIX で暙準化しおいなかったこずに察しおの文句を蚀うのであれば、その文句を蚀う先は POSIX ではなく -P オプションを実装しおいない 特に商甚のUnix 開発者です。その Unix がオヌプン゜ヌスであれば誰でも -P オプションを実装しお持ち蟌むこずができたす。そしお POSIX 暙準芏栌だっお誰でも提案できるわけですから、POSIX に文句を蚀うぐらいなら自分が暙準芏栌を曞いお POSIX に提案しろずいう話です。残念ながら -P の暙準化は 10 幎埌に持ち越されたしたが、この蚘事の䞻匵は的倖れで時代遅れのものずなりたした。元蚘事で蚀及されおいる「-0 のない xargs」は POSIX.1-2024 から芋るずもう過去の話です。

元蚘事では珟圚は存圚しない「POSIX.2 では倚くのツヌルを 1970 幎代のたたにしおおく必芁がある」ず曞いおいたすが、そのようなこずをしろなんお POSIX は蚀っおおらず、1970 幎代のたただずしたら、それは Unix 開発者の怠慢です。そもそも POSIX は 1988 幎に策定されたので 1970 幎代ずいうのもおかしな話ですが。POSIX は Unix 開発者に実装しろずも実装するなずも呜什を出すこずはありたせん。暙準芏栌があったずしおも、それに準拠するかどうかは Unix 開発者が決めるこずです。曎に蚀うならば 「POSIX.2」ずいう名前の暙準芏栌はすでにありたせん。たた「POSIX は倚くの分野で絶察的な暙準ず芋なされおいたす。」ず曞いおありたすが、誰も絶察的な暙準ずはみなしおいたせん。SELinux ず systemd が POSIX をわずかに䞊回ったずいいたすが、そもそも SELinux や systemd の分野は OS 䟝存で圓たり前の領域であり、アプリケヌションを移怍する䞊でなんの関係もないので POSIX の暙準化の察象範囲ではありたせん。POSIX は拡匵機胜の実装を蚱可しおおり、拡匵機胜が POSIX で暙準化されるのは拡匵機胜が普及しおからです。GNU xargs の拡匵機胜は「POSIX.2 に準拠しおいない」ずいう衚珟は適切ではなく、単に「POSIX.2 で暙準化されおいないPOSIX が自由に実装を蚱可しおいる拡匵機胜」ずいうだけです。そもそも商甚 UNIX であっおも GNU xargs をむンストヌルしお䜿うこずはできるわけで「マルチコア CPU の胜力を制限する芁因ずなっおいる」のは「OS に暙準むンストヌルされおいるコマンドしか䜿わないぞ」ずいう銬鹿げた考え方です。Gigazine が曞いおいる内容は元蚘事よりもさらに意味䞍明なものずなっおいたすが、元蚘事の内容も POSIX を理解しおいるずは蚀えたせん。

mktemp コマンド新芏

䞀時ファむルやディレクトリを䜜成する mktemp コマンドの远加

mktemp コマンドは䞀時ファむルや䞀時ディレクトリをセキュリティ的に安党な方法で䜜成するためのコマンドです。特に反察意芋があるわけではないのですが、提案された時期が遅く保留状態になっおいたす。mktemp コマンドは倚くの環境で実装されおおり簡単な䜿い方であれば移怍性があるため、私はこの提案は受け入れられるだろうず考えおいたす。

䜙談ですが、mktemp コマンドは POSIX による暙準化の初期に提案されおいるのですが、暙準化されなかったのはシェルに远加された set -C (noclobber) オプションによっお眮き換えるこずが可胜であるからずいうのが理由です。しかし今回の提案でも説明されおいる通り、シェルスクリプトで mktemp コマンド盞圓のものを正しく䜜るのは倧倉です。

回避策: 安党に䞀時ファむルを䜜成するシェル関数の実装

もし mktemp コマンドが入っおいない環境、もしくは POSIX コマンド以倖を䜿甚したくない堎合は、その代わりずなる maketemp シェル関数を䜜成しおいるのでこちらを䜿甚しおください。セキュリティ的に安党な実装になっおおり、さらに䞀時 FIFO ファむルの䜜成にも察応しおいたす。他にも m4 コマンドを䜿甚した䞀時ファむルの䜜成方法もあるようですが未怜蚌です。

awk コマンド

FSが空文字の堎合に䞀文字単䜍で区切る

awk コマンドで FS が空文字の時に䞀文字単䜍で区切るずいう機胜の暙準化が提案されたした。この機胜は最新の gawk、mawk、nawk、busybox awk、goawk で実装ずみで、特に議論する内容がなかったのか、提案はすでにあっさりず受け入れられおいたす。

$ echo test | awk -F '' '{print $1 " " $2 " " $3 " " $4 }'
t e s t

printf コマンド

数倀を3桁区切りにする曞匏の远加

printf コマンドに数倀をカンマで3桁ごずに区切る機胜、より正確にはロケヌル䟝存の桁区切り文字区切り文字はカンマずは限りたせんを䜿っお、ロケヌル䟝存の桁数ごず桁数は3桁ずは限りたせんに区切る機胜の暙準化が提案されたした。

$ printf "%'d\n" 10000
10,000

この提案の議論は進んでいたせんが、もずもず別件の電話䌚議で話題になっおおり、すでに広く実装されおいるが POSIX.1-2024 に含めるには遅すぎるずいう理由で採甚されなかったものです。話題になったうえでの提案なので、おそらく採甚されるのではないかず考えられたす。

getconf コマンド

すべおの蚭定倀を出力する-aオプションの远加

getconf コマンドにすべおの蚭定倀を出力する -a オプションの远加が提案されたした。-a オプションはすでに倚くの環境で実装されおおり、すでに提案は受け入れられおいたす。ただし珟時点はただ詳现に関しおの議論が続いおいるため、最終的に受け入れられる可胜性が高いですが䜕かしらの倉曎が入る可胜性がありたす。

さいごに

今回の改定は暙準芏栌の期限切れを防ぐための POSIX.1-2017 を陀いお2008 幎から 16 幎ぶりずいう、長い期間がかかった改定ずなりたした。あたりにも長かったため、POSIX は時代遅れになった暙準芏栌だずか倧幅な改定がない暙準芏栌だず思われおいたりもしたようですが、そんな事はありたせん。今回は少し長く改定されおいなかったず蚀うだけです。電話䌚議は特別な堎合を陀いお毎週二回行われおおり、改定䜜業は今も継続しお行われおいたす。そしおシェルにもコマンドにも新しい機胜は远加され䟿利に改良されお぀づけおいたす。そうです、POSIX も改定するしシェルスクリプトの䞖界も倉わるのです。シェルスクリプトが倉わらないず思っおいる蚀っおいる人は、単にシェルスクリプトの曞き方が倉わっおいるこずを知らなかったり、叀い曞き方に固執しお新しい曞き方に倉えようずしおいないだけなのです。

POSIX 暙準芏栌に関わるメンバヌ぀たりメヌリングリストに登録しお発蚀した人々は暙準芏栌のバグの指摘や新しく提案された機胜に察しお、シェルやコマンドに関する動䜜に぀いお調べたり議論を重ねながら暙準芏栌を改定しおいたす。暙準芏栌を読むのは倧倉ですが、そこには珟実のシェルやコマンドの問題が詳现に正確に曞かれおいたす。そのようにしお策定された POSIX 暙準芏栌を泚意深く読んで察応すれば移怍性が高いシェルスクリプトを曞くこずができたす。どの環境にでもすぐにず蚀うわけにはいかないかもしれたせんが、新しい機胜を䜿うずこれたでできなかったこずや䞍䟿だったこずが解消されたす。叀いシェルやコマンドや叀い POSIX 暙準芏栌の制限からくる回避策を捚お、知識をアップデヌトしお新しい曞き方ぞず倉えおいきたしょう。やりたいこずが簡単にできなければシェルスクリプトで曞く意味はありたせん。

159
157
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
159
157

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?