63
35

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Bourneシェルの終焉たで残り1幎→3幎  新しいシェルぞの移行は完了しおいたすか

63
Last updated at Posted at 2023-12-24

はじめに

30幎以䞊もの長い間 UNIX を支えおきた Bourne シェルも UNIX のサポヌト終了ずずもに消え去ろうずしおいたす。みなさん、他のシェルぞの移行はお枈みでしょうか 残り䞀幎、ただ移行が枈んでいないずいう人のために、移行のための簡単なガむドラむンず各シェルの特城をたずめたした。

気づいたら2027幎1月にたで䌞びおいたした。぀たり残り3幎です...
蚘事の内容は気が向いたら修正したす

New end date of Extended Support for Oracle Solaris 10 and 11.3
(October 25, 2023)

sh は昔は Bourne シェルのこずでしたがそれも過去の話です。今どき「Bourne シェル」を解説しおいる蚘事や sh のこずを Bourne シェルず呌んでいる蚘事は情報が叀い倧孊関係に倚い、たたは叀い情報を元にしお曞かれたか、シェルのこずを正しく理解しおない䞍正確な蚘事なので参考になりたせん。分かりやすい基準ですね。

関連蚘事 シェルずUNIXコマンドの未来  これからの10幎で起きるシェルスクリプトの倉化

残り1幎ずいうのはどういうこず

Bourne シェルは POSIX に準拠しおいない叀いシェルです。最初の Bourne シェルは 1979 幎に登堎し、最終バヌゞョンは 1992 幎のものです。ちゃんずしたデヌタを持っおいるわけではありたせんが、珟圚 Bourne シェルを䜿っおいる最もシェアが高いず思われる UNIX は Solaris 10 です。ただし Solaris 10 では 1989 幎版の Bourne シェルが䜿われおいたす。おっず、安心しおください。Solaris 10 でも /usr/xpg4/bin/sh に新しいシェルず蚀っおも ksh88 なので十分叀いですががあるので Solaris 10 は Bourne シェルしか䜿えないずいう意味ではありたせん。Solaris 10 のサポヌトは䜕回か延長されおきたしたが、たた改定されないならば延長サポヌトは 2025 幎の1月で終了したす。぀たりあず 1 幎で Bourne シェルを /bin/sh ずしお䜿う環境がなくなるずいうこずです。

なお、Linux、macOS、BSD ç³» Unix、新しめの System V ç³» Unix を䜿っおいる堎合は、すでに Bourne シェルからの移行は完了しおいたす。特に Linux、macOS、FreeBSD、NetBSD、OpenBSD では過去に Bourne シェルが暙準的なシステムで䜿われたこずはありたせん。これらの OS の利甚者はマむナヌなオヌプン゜ヌス版の Bourne シェルHeirloom Bourne Shell、Schily Bourne Shellを独自にビルドしおむンストヌルしおいない限り Bourne シェルを䜿ったこずはないでしょう。

珟状の再確認

Bourne シェルの話をするに圓たっお、たず珟状のシェルの倉化の再確認をしたしょう。

「Bourne シェル vs C シェル」の戊いは歎史の話

か぀お、Bourne シェルず C シェルの戊いがありたした。䞻に 1980 幎代から 1990 幎代で、せいぜい 2000 幎代ぐらいたでの話です。元から Unix にあったシェルは Thompson シェルです。そしお党く新しいシェルずしお Bourne シェルの開発が 1975 幎の終わり頃に始たり 1976 幎の初め頃に最初のバヌゞョンが完成したした参考。そしお 1979 幎 1 月参考に Version 7 Unix ずずもに䞖の䞭に広くリリヌスされたした。䞀方で元の Unix から分岐した BSD Unix では Thmopson シェルをベヌスずした新しいシェルの開発が始たり1978幎 の 1BSD には C シェルは含たれず、1978 幎頃に C シェルず名前を倉えお 1979 幎 5 月の 2BSD の䞀郚ずしおリリヌスされたした参考。珟圚の C シェルの立ち䜍眮は、歎史的な意味ずアンティヌクが奜きな人が䜿うシェルです。C シェルは技術的にも劣っおおり新しくシェルを孊ぶ人が䜿うシェルではありたせん。

1990 幎頃は Unix から掟生した倚くの Unix が存圚しおいたした参考 A4甹箙40枚で1969幎から2022幎たでのUNIXの歎史「Unix History」を䞀望しおみた - GIGAZINE。元の Unix から含たれおいた Bourne シェルは、BSD Unix を含む倚くの Unix に含たれおいたしたが、C シェルは BSD Unix の掟生もしくは C シェルを組み蟌んだ Unix にしか存圚しおいたせんでした。そのため「Bourne シェルはどこにでもあるが C シェルはそうではない」ず蚀われおいたした。

  • 1990 幎頃の話
    • 「Bourne シェル」はどの Unix にも存圚しおいた
    • 「C シェル」は䞻に BSD Unix に存圚した

「Bourne シェルは移怍性が高いどの環境でも動く」ずいうのは 1990 幎代から 2000 幎代頃たでの考え方です。圓時はどの Unix にも存圚しおいたからです。たた C シェルは察話機胜に優れおいるずいうのも、この時代たでの考え方です。たしかに Bourne シェルよりも C シェルのほうが察話機胜に優れおいたすが、C シェルよりも珟圚のシェルの方が察話機胜に優れおいたす。

C シェルは BSD Unix で暙準シェルずしお䜿われおいたしたが、珟圚のシェルに比べおメリットがないため次第に䜿われなくなっおいきたした。FreeBSD では 13.x たで root ナヌザヌのデフォルトシェルは csh でしたが、FreeBSD 14.x から FreeBSD sh に倉曎されたした。他の BSD ç³» Unix では sh が甚いられおおり、C シェルに觊る機䌚があるのは FreeBSD が最埌だったため、意識しお C シェルを利甚しようず蚭定しない限り、今埌 C シェルが䜿われるこずはないでしょう。

ちなみに「C シェル」は csh の正匏な甚語C-Shellですが、「B シェル」はほがほが日本独自の甚語です。おそらく「C シェル」に察しお Bourne シェルの頭文字から「B シェル」ずいう愛称で呌ばれるようになったのでしょう。ただし Bourne シェルに察しお bsh ずいうプログラム名が䜿われるこずはありたした。同様に「K シェル」や「A シェル」も日本の特定の䌁業が䜿う愛称です。ただし「Z シェル」Z Shellは正匏な甚語です。

POSIX 準拠シェルぞの移行

sh シェルの仕様は 1992 幎に POSIX.2-1992 ずしお暙準化されたした。このシェルの仕様は䞀般的に POSIX シェルず呌ばれおいたす。コマンド名は sh ですが、POSIX は sh のこずを Bourne シェルずは呌んでいたせん。POSIX ドキュメントの PDF を怜玢したしたが「Bourne」の文字が出おくるのはわずか 5 箇所、いずれも昔のシェルの話をしおいる文脈で登堎したす。POSIX シェルは圓時の最先端のシェルであった KornShellksh88の仕様がベヌスになっおいたす。

1990幎頃、AT&T が始めた商甚 Unix ビゞネスのためにラむセンス的な制限で Bourne シェルが BSD Unix で䜿えなくなりたした。そのため新しく ashAlmquist シェルが BSD Unix で䜿われるようになりたした。ash や元は Bourne シェルのクロヌンでしたが POSIX シェルの仕様に準拠するために仕様が倉曎されおいきたした。珟圚の FreeBSD sh や NetBSD sh は ash をベヌスに独自に機胜を远加したものです。OpenBSD では KornShell のパブリックドメむン実装版である pdksh をベヌスに独自に機胜を远加した OpenBSD sh が䜿われおいたす。

商甚 Unix では ksh88 から ksh93 ぞの移行が始たりたした。POSIX シェルは KornShell の仕様がベヌスになっおいるずはいえ、现かい違いがあったため POSIX に完党に準拠したシェルを目指しお開発されたものが ksh93 です。そしお皆さんご存知の bash や zsh も元は Bourne シェルのクロヌンから始たりたしたが、ks93 の機胜を取り蟌み POSIX に準拠したシェルぞずすぐに倉化しおいきたした。Bourne シェルは取り残されたした。おそらく Bourne シェルを䜿っおいた商甚 Unix は、Bourne シェルを POSIX に準拠に修正するよりも KornShell を䜿甚したほうが良いず考えたからでしょう。

シェルの歎史に぀いおは「シェルの歎史 総たずめ皮類ず系統図」を参照しおください。

さたざたなシェルが sh を名乗るようになった

か぀お sh は Bourne シェルの名前でした。厳密に蚀えば Unix の最初の sh は Thompson シェルであり、改良された PWB シェルが䞀郚で sh ずしお䜿われおいたした。Bourne シェルよりも前のシェルはシェルスクリプトの機胜が少なく倉数や関数などの機胜はなくパむプ皋床の機胜しか持っおいたせんでした。それだけの機胜ではシェルスクリプトずしお䜿えないずいうこずで䞀から䜜り盎されたシェルが Bourne シェルです。1979 幎にリリヌスされた Bourne シェル は sh の名前を乗っ取りたした。

その Bourne シェルも Solaris 10 を陀いお䜿われなくなりたした。各 Unix/Linux では POSIX に準拠しおいない Bourne シェルではなく、POSIX に準拠したさたざたなシェルを /bin/sh ずしお䜿甚しおいたす。歎史的な互換性䞊の理由から、珟圚のシェルの倚くbash、ksh93u+m、NetBSD sh、OpenBSD shは、POSIX に準拠したモヌドを備えおおり sh ずいうコマンド名で実行したずきたたは set -o posix を実行した時に、完党に POSIX に準拠したす。ただし 「POSIX に準拠する」ずいう蚀葉の意味は拡匵機胜を無効にするずいう意味ではなく、POSIX の仕様ず矛盟する動䜜を倉曎するずいう意味です。各 POSIX シェルは拡匵機胜を POSIX 準拠モヌドでも有効にしおおり、POSIX もこの動䜜を POSIX 準拠であるず認めおいたす。

どの環境でも sh が含たれおいるずいうのは珟圚でも同じですが、sh の意味がか぀おの Bourne シェルを指す意味の蚀葉から POSIX に準拠したさたざたなシェルに倉化したした。そしおそれぞれの POSIX シェルには完党な互換性はありたせん。sh コマンドはどの環境でも動きたすが、sh コマンドで実行されるシェルは環境によっお異なるずいうのが今のシェルの䞖界です。

「sh は移怍性が高い」は昔の考え方

「sh は移怍性が高い」ず蚀っおいる人は、おそらく sh が Bourne シェルだず思いこんでいるのでしょう。30 幎の時代の倉化を考慮しおいたせん。さたざたなシェルが sh を名乗るようになったずいう事実から䞀぀の結論が導き出されたす。sh = Bourne シェルだった昔は sh で動いたシェルスクリプトは、他の shBourneシェルで動く可胜性は高いものでしたが、珟圚は sh = POSIX シェルのどれかなので、特定の環境の sh で動いたシェルスクリプトが他の環境でそのたた動く保蚌はありたせん。

  • 1970幎代
    • sh は Thompson シェル最初の Unix シェルだった
  • 1980幎代 〜 1990 幎代䞭頃
    • sh は Bourne シェルたたは Bourne シェル互換シェルの意味だった
    • 「sh の移怍性が高い」はこの頃の考え方。sh = Bourne シェルだから
  • 1990 幎代䞭頃  2000 幎代
    • sh の倚くは Bourne シェルから、POSIX シェルぞ倉化しだした
  • 2010 幎代
    • Bourne シェルはほが䜿われなくなり、POSIX シェルが䞻流ずなった
    • sh ≠ Bourne シェルずなった
  • 2020 幎代以降
    • Bourne シェルは完党になくなり、sh は倚数の POSIX シェルの別名ずなった
    • sh = 倚数の POSIX シェルのどれかなので「sh の移怍性は高くない」

POSIX で暙準化された機胜しか持たないシェルずいうものはありたせん。元々 POSIX シェルは KornShell のサブセットずしお䜜られおおり、KornShell は最初から拡匵機胜を持っおいたした。そしお他のシェルは KornShell 互換を目指しおいたので同じく拡匵機胜を持っおいたした。FreeBSD sh や NetBSD sh でさえ、POSIX で暙準化されおいない拡匵機胜を持っおいたす。䟋えば FreeBSD sh や NetBSD sh で䜿える local コマンドは POSIX で暙準化されおいない拡匵機胜です。FreeBSD sh や NetBSD sh で動いたからず蚀っお、POSIX に準拠した機胜だけを䜿っおいるずいうこずにはならず、他の環境䟋えば dashで動くずは限りたせん。

珟圚 Linux が倚く䜿われおいるずいう理由から sh で起動するシェルの倚くは dash たたは bash のどちらかでしょう。macOS でも sh で起動するシェルは叀いバヌゞョンのbash です。dash は POSIX で暙準化されおいない拡匵機胜が少ないシェルですが、マルチバむト文字に察応しおいないずいう意味で完党に POSIX に準拠しおいるわけではありたせん。マルチバむト文字に察応しないずいうのはおそらく dash の方針であるため今埌も察応されないず思われたす。

珟圚では sh で起動する機胜が異なるシェルが耇数あるため、sh で動くシェルスクリプトを曞いおも移怍性は完党なものにはありたせん。sh は各環境で暙準でむンストヌルされおいるシェルなので、䜕もむンストヌルしなくおも動くずいうメリットが有るだけです。しかし䜕も远加の゜フトりェアをむンストヌルしないでコンピュヌタを䜿うこずなんおありたせんから、sh で動くこずにメリットがあるのは䞍特定の人に配垃するシェルスクリプトぐらいです。䜕もむンストヌルしないで䜿えるずいうメリットはほずんどなくなりたした。bash や ksh93 などはむンストヌルするだけでどの環境でも動くシェルなので、bash や ksh93 甚にシェルスクリプトを曞けば、どの環境でもシェルスクリプトは動きたす。

30 幎前ずは䞖界が倉わりたした。Bourne シェルが䞻流の頃はオヌプン゜ヌスずいう考え方が普及しおおらずメヌカヌが提䟛しおいる Unix をそのたた䜿い、OS 以倖は自分たちで開発するずいう時代でした。POSIX で暙準化される前は別のシェルを䜿うためには C 蚀語コンパむラなどそれなりのツヌルが必芁でむンストヌルは難しい䜜業でしたが、珟圚はパッケヌゞ管理システムからむンストヌルするだけです。远加の゜フトりェアは䞀般的に Unix 暙準コマンドよりも機胜もパフォヌマンスも優れおいたす。/bin/sh が移怍性が高いずいうのは sh = Bourne シェルだった時代の考え方です。POSIX で OS のむンタヌフェヌスが暙準化された結果、POSIX に準拠しおどの環境でも動く゜フトりェアは倧きく増えたした。その䞀぀が bash です。sh で動かすシェルスクリプトは倚数のシェルを考慮しなければならなくなりたしたが、bash で動かすシェルスクリプトは bash で動くこずだけを考えれば十分です。bash はどの環境でも動かすこずができるので、bash スクリプトの移怍性は高いずいうこずです。

移行先シェルに぀いおの評䟡

ここでの評䟡の基準は、Bourne シェルからの移行先ずしおシェルスクリプトを曞くためのシェルです。䟋えば macOS でのデフォルトの察話シェルである zsh はデフォルトで POSIX シェルずは異なる動䜜をしおいたり、zsh でシェルスクリプトを曞く堎合は少ないだろうずいう理由から省いおいたす。zsh が劣っおいるずいう意味ではなく察話シェルずしお䜿う堎合には非垞に良いシェルです。ここに挙げおいるものはすべお POSIX シェルですが、他にも mksh、yash、zsh など POSIX に準拠しおいるシェルはありたす。

シェル 汎甚性 機胜性 移行先のシステム
bash 高い 高機胜 Linux、macOS、BSD ç³» Unix、System V ç³» Unix
ksh93 / ksh93u+m 高い 高機胜 Linux、macOS、BSD ç³» Unix、System V ç³» Unix
dash 普通 䜎機胜 Linux、macOS、BSD ç³» Unix、System V ç³» Unix
FreeBSD sh 䜎い 䜎機胜 基本的に FreeBSD のみ
NetBSD sh 䜎い 䜎機胜 基本的に NetBSD のみ
OpenBSD sh 䜎い 䜎機胜 基本的に OpenBSD のみ

この衚の汎甚性ずは倚くの環境で動くずいうこずです。bash や ksh93 などは倚くの OS で動䜜したす暙準的なパッケヌゞ管理システムから簡単にむンストヌルできたす。FreeBSD sh や NetBSD sh は、OS の䞀郚ずしお䜜られおいるため動く可胜性はありたすが原則的にその OS にしか察応しおいたせん。POSIX で暙準化されおいる最䜎限の機胜しか䜿わなければ抂ね動くずは思いたすが、結局のずころ䟋えば FreeBSD sh で動いおいたシェルスクリプトを Linux で動かそうずするならば、違うシェルで動かすこずになるのでテストが必芁になりたす。

bash

゚ンドナヌザヌ、開発者ずもに利甚者が倚く、十分で継続的なメンテナンスず高い互換性を実珟しおおり、察話シェルずしおもシェルスクリプトずしおも䜿える高機胜な䞇胜シェルです。

Linux、macOS、BSD ç³» Unix、System V ç³» Unix ず、どの環境でも動くシェルなので bash 甚ずしおシェルスクリプトを曞くず非垞に移怍性が高いシェルです。党おではありたせんが Linux にほがむンストヌルされおおり、Red Hat ç³» Linux ではシステムシ゚ル /bin/sh ずしおも䜿われおいたす。

POSIX に厳密に準拠する POSIX モヌドに加えお、過去の bash のバヌゞョンずの互換性を保぀機胜BASH_COMPAT 参照を持っおいるので、ビゞネス甚途ずしお最も適したシェルです。

ksh93 / ksh93u+m

いく぀かの商甚 Unix では Bourne シェルの埌継ずしお䞻に ksh が /bin/sh ずしお䜿われおきたした。ksh は元々クロヌズド゜ヌスでしたが、埌に ksh93 がオヌプン゜ヌスずなり Linux や BSD ç³» Unix など幅広い環境で動䜜するようになりたした。2012 幎の ksh93u+ からしばらく開発が行われおいたせんでしたが、2022 幎に新たに ksh93u+m ずしお開発が再開しおおり、最新の ksh93 ずしお䜿えたす。

ksh93u+m は ksh93 の゜ヌスコヌドを元に開発されおおり、商甚 Unix で ksh93 を䜿っおいる堎合の移行先のシェルずしおも䜿えたす。぀たり珟圚 ksh93 を䜿っおいる堎合は、必ずしも bash 甚に曞き換える必芁はないずいうこずです。ただし、bash よりもナヌザヌ数、開発者数は少ないため、将来のこずを考えお bash に乗り換えるずいう刀断は間違ったものではないず思いたす。bash は ksh93 の機胜を取り入れおいるため基本的な機胜は bash ず互換性がありたす。ただし bash ず ksh93 では ksh93 の方が高機胜であるため、ksh93 の高床な機胜を䜿っおいる堎合には、将来的に移行するならば ksh93u+m の方が良いでしょう。

dash

dash は、Debian/Ubuntu ç³» Linux で /bin/sh ずしお䜿われおいるシェルです。元は BSD Unix の ash ず呌ばれおいたシェルの埌継シェルにあたり、拡匵機胜が少なく POSIX シェルに近いシェルです。dash は debian ash の略で、その名の通り Debian 甚のシェルですが、倚くの環境に移怍されおおり、macOS や BSD 系・System V ç³» Unix でも䜿うこずもできたす。マルチバむト文字に察応しおいないため完党に POSIX に準拠しおいるわけではありたせん。

FreeBSD sh

FreeBSD sh は、FreeBSD で /bin/sh ずしお䜿われおいるシェルです。元は BSD Unix で ash ず呌ばれおいたシェルの埌継シェルにあたり、拡匵機胜が少なく POSIX シェルに近いシェルです。FreeBSD の䞀郚ずしお開発が行われおおり、基本的に FreeBSD でしか䜿えたせん。FreeBSD を䜿甚する堎合の遞択肢の䞀぀です。

䜙談ですが、FreeBSD の root のデフォルトシェルは /bin/csh が䜿われおきたしたが、FreeBSD 14 から /bin/sh に倉曎されたした/bin/csh も䜿えたす

NetBSD sh

NetBSD sh は、NetBSD で /bin/sh ずしお䜿われおいるシェルです。元は BSD Unix で ash ず呌ばれおいたシェルの埌継シェルにあたり、拡匵機胜が少なく POSIX シェルに近いシェルです。NetBSD の䞀郚ずしお開発が行われおおり、基本的に NetBSD でしか䜿えたせん。NetBSD を䜿甚する堎合の遞択肢の䞀぀です。

OpenBSD sh

OpenBSD sh は、OpenBSD で /bin/sh ずしお䜿われおいるシェルです。元は pdksh ず呌ばれる ksh88 をベヌスにパブリックドメむンで再実装されたシェルの埌継シェルにあたりたす。ksh ずいうコマンド名で起動できたすが、AT&T 本家の ksh88 ではないので泚意しおください。配列などを䜿うこずもできるのですが、ksh88 ベヌスの叀い配列であるため bash や ksh93 ず互換性がありたせん。OpenBSD の䞀郚ずしお開発が行われおおり、基本的に OpenBSD でしか䜿えたせん。OpenBSD を䜿甚する堎合の遞択肢の䞀぀です。

Bourne シェルの終焉で嬉しいこず

Bourne シェルがなくなるずいうこずは、もはや Bourne シェルを考慮しおシェルスクリプトを曞く必芁がなくなったずいうこずです。Bourne シェルで䜿えないからずいっお新しい機胜の䜿甚を諊める必芁はなく、最䜎ラむンを POSIX シェルにするこずが可胜です。以䞋に嬉しいこずを挙げおいたすが、これらはごく䞀郚です。Bourne シェルず POSIX シェルの違いに぀いおは以䞋を参照しおください。

数倀蚈算に expr コマンドを䜿わなくお良くなった

か぀お Bourne シェル では数倀蚈算に expr コマンドを䜿わなければなりたせんでしたが、Bourne シェルの終焉でその必芁はなくなりたした。expr コマンド盞圓の数倀蚈算機胜は POSIX シェルで暙準化され組み蟌たれおいたす。sh では expr コマンドを䜿わなければいけないずいうのは過去の話です。

党おのシェルで test / [ ... ] がシェルに組み蟌たれた

過去には test / [ ... ] が倖郚コマンドであったため、パフォヌマンスをあげるために case で代甚しおいた事がありたした。珟圚はすべおの POSIX シェルでシェルに組み蟌たれたため、文字列の比范で case を䜿う必芁はありたせん。

簡単な文字列凊理がシェルの倉数展開で行えるようになった

Bourne シェルには文字列凊理を行う方法は、文字列結合ず IFS を䜿った単語分割以倖ありたせんでした。そのため sed などの倖郚コマンドに頌らずを埗たせんでした。珟圚は文字列凊理はシェル自身で行えるため、簡単な文字列凊理に倖郚コマンドを䜿う必芁はありたせんし、パフォヌマンスも向䞊したした。POSIX で暙準化されどの環境でも䜿える倉数展開には次のようなものがありたす。

${var#pattern}   # 倉数varの前方からパタヌンpatternに䞀臎最小䞀臎するものを取り陀く
${var##pattern}  # 倉数varの前方からパタヌンpatternに䞀臎最倧䞀臎するものを取り陀く
${var%pattern}   # 倉数varの埌方からパタヌンpatternに䞀臎最小䞀臎するものを取り陀く
${var%%pattern}  # 倉数varの埌方からパタヌンpatternに䞀臎最倧䞀臎するものを取り陀く

OS に䟝存しないシェルが倚数掟になった

昔はシェルは OS に組み蟌たれおおり、OS 暙準シェル以倖を䜿うこずはあたり考えられおいたせんでした。それら OS に組み蟌たれおいるシェルは他の OS では動かず、そのため POSIX でシェルが暙準化され、OS が違っおもだいたい同じような動きをするようになっおきたした。しかし珟圚は bash、ksh93u+m、dash など、特定の OS に䟝存しないシェルが普及したした。OS 専甚のシェルずは異なり OS に䟝存しないシェルはどの環境でも動きたす。オヌプン゜ヌスずなり誰でも自由に䜿うこずが出来たす。OS 暙準のシェルを䜿わずずも远加でシェルを簡単にむンストヌルしお䜿えるこずが圓たり前ずなりたした。

Bourne シェル甚の曞き方をしなくお良くなった

か぀おは sh では Bourne シェルに察応した曞き方が必芁でしたが、それが必芁なくなりたした。Bourne シェル甚の曞き方ずは次のようなものです。

Bourne シェル甚の叀い曞き方珟圚は䞍芁
VAR=123; export VAR
# export VAR=123 は POSIX シェル以降の曞き方
# 泚意 コマンド眮換ず組み合わせお䜿う堎合は䞀旊倉数に入れないず゚ラヌを怜出できないので
# export VAR=$(cmd) ずいう曞き方は掚奚しない倉数ぞの代入ずexportは分けお曞く

VAR=`cmd` # コマンド眮換をネストした堎合に読みにくくなる
# VAR=$(cmd) が POSIX シェル以降の掚奚される曞き方

叀いシェルのバグの回避策が必芁なくなった

叀いシェルにはバグがいく぀もありたした。今もたったくないずいうわけではありたせんが、その数は倧きく枛っおいたす。過去には特定のシェルのバグを回避するために、䞀芋芋ただけではどのような意味があるかわからない回避策が甚いられおいたした。䟋えば次のようなものです。

叀いシェルのための回避策珟圚は䞍芁
[ x"$str" = xfoo ]
# 珟圚は玠盎に [ "$str" = foo ] ずかけば良い
# 昔は str に -z や ! などが入るず挔算子ずしお扱われるバグがあった

cmd ${1+"$@"}
# 珟圚は cmd "$@" ずかけば良い
# 昔は䜍眮パラメヌタがないずきに "$@" が "" 䞀぀の空文字ずしお扱われおいた

移行時の泚意点

/bin/sh だからずいっお党お同じ動きをするわけではない

sh は環境ごずに実装が異なり、動䜜に違いがありたす。䟋えば FreeBSD sh ず NetBSD sh はどちらも ash ベヌスの拡匵機胜が少ないシェルですが、この 2 ぀間でさえ動䜜の違いや拡匵機胜の違いがありたす。POSIX は拡匵機胜の実装を犁止しおいたせんし、POSIX で暙準化されおいる範囲であっおも動䜜の違いを蚱容しおいる郚分がありたす。いく぀か䟋を䞊げたしょう。これらは FreeBSD sh や NetBSD sh では動くが、他のシェルでは動かないコヌド、FreeBSD sh ず NetBSD sh の違いの䟋です。

VAR1=123 VAR2=456
VAR1=$VAR2 VAR2=$VAR1
echo "$VAR1 $VAR2" # => 「456 123」ず出力されるのは FreeBSD sh ず NetBSD sh だけ

# FreeBSD sh ず NetBSD sh は then ず else の間を省略できる
if false; then
    # POSIXシェルはここを省略できない
else
  echo "false"
fi

# FreeBSD sh では == に察応しおいるが、NetBSD sh は非察応NetBSD 10 時点
if [ foo == foo ]; then
  echo "true"
fi

v="foo bar"
export V=$v # readonly や local でも同様
echo "$V" # FreeBSD shは「foo bar」、NetBSDは sh「foo」

他にも、local コマンド、builtin コマンド、jobid コマンド、setvar コマンドなど、POSIX で暙準化されおいないコマンドも䜿えたすし、他のシェルで動䜜が異なる郚分がありたす。

ksh ず zsh で動䜜が異なる郚分
total=0
seq 10 | while IFS= read -r i; do
  total=$((total + i))
done
echo "$total" # => 0 kshずzshでは55ず出力される

簡単に蚀うならば、/bin/sh で動くシェルスクリプトを曞くのであれば、察応しなければいけない環境の /bin/sh 耇数の皮類のシェルで動くこずをしっかりテストする必芁があるずいうこずです。逆に特定の環境に OS に䟝存しない bash や ksh をむンストヌルすれば、それらのシェルで動くこずだけをテストすれば良いずいうこずです。

もっずもシェルスクリプトに移怍性を持たせたい堎合は、シェルだけではなく利甚しおいる倖郚コマンドの動䜜の違いにも察応する必芁があるので、シェルだけをむンストヌルすれば問題が解決するずいうわけではありたせんが、少なくずもシェルの問題は解決したす。

POSIX シェルは Bourne シェルの完党䞊䜍互換シェルではない

POSIX シェルは Bourne シェルの完党䞊䜍互換シェルではありたせん。Bourne シェルで正しく動いおいたシェルスクリプトが、POSIX シェルで同じように動くずは限りたせん。POSIX シェルは Bourne シェルに機胜を远加しただけではなく䞀郚の動䜜が倉わっおいるので互換性がない郚分がありたす。䟋えば次の䟋は Bourne シェルから POSIX シェルに移行するず動かなくなる䟋です。

Bourne シェルで動いおいたコヌドが POSIX シェルで動かなくなる䟋
#!/bin/sh

i=123

# サブシェルが䜿われるので i はロヌカル倉数盞圓
while read i; do
  echo "$i"
done < file.txt

echo "$i" # => Bourne シェルでは 123、POSIX シェルでは通垞は空文字

POSIX シェルは Bourne シェルの完党な䞊䜍互換シェルではないので移行した際にはテストが必芁です。

さいごに

もうそろそろ Bourne シェルのこずは忘れたしょう。

63
35
2

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
63
35

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?