48
38

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 5 years have passed since last update.

Unix/Linux シェル考叀孊 シェルスクリプトが本物のプログラミング蚀語である理由

48
Last updated at Posted at 2021-06-01

はじめに

タむトルは「Unix考叀孊」のパクリですがこの蚘事ず盎接の関係はありたせん。Unix 誕生時点のシェルから POSIX シェルが策定されるたでのシェルの歎史を調べおみたした。サブタむトルが埮劙にタむトルずずれおる感じがするかもしれたせんが、この蚘事はもずもずシェルスクリプトは䜕を目指しお蚭蚈された蚀語なのか疑問になっお調べ始めたものだからです。時々「シェルスクリプトじゃなくお本物のプログラミング蚀語で曞くべきだ」ずいうような話を目にしたすが、実際はシェルスクリプトはプログラミング蚀語なのかそうではないのかなので、むしろサブタむトルのほうが本題です。

゜ヌスは wikipedia日本語版は情報が叀いので䞻に英語版およびそこからの倖郚リンクなどを適圓に調べおたずめたものです。内容に疑問に感じる堎合は独自で調べるのをおすすめしたす。ちなみに ~sven_mascheck/ はおすすめです。この蚘事ずは比べ物ならない圧倒的な情報量を誇っおいたす䟋えば #! の由来ずか。PWB シェルに関しおは「Unix 考叀孊」も参照したした。たた私の興味の察象が POSIX シェル、およびその元ずなった KornShell ずその盎系の先祖である Bourne シェルなので C シェルやその他のシェルに぀いおは最䜎限しか調べおいたせん。気が向いたら远蚘するかもしれたせん。もし間違いなどがあれば教えおいただけるず助かりたす。

**2021-06-04 远蚘 この蚘事を曞いた経緯ずか結論に興味がある人ぞ**
どうもこの蚘事を曞いた経緯ずか結論に興味がある人がいるようなので少し説明を远蚘したす。䞊では省略したしたがこの蚘事を曞き始めた盎接のきっかけは[別件](https://qiita.com/ko1nksm/items/efb9693a79412f445a83)でたたたた[このファむル](https://github.com/modernish/modernish/blob/master/share/doc/modernish/DESIGN.md)に次のような曞かれおあるのを芋぀けたからです。

The shell is an actual programming language. That's how it was designed and advertised right from the early days of the Bourne shell. Unfortunately, few take it seriously as such.

シェルは実際にプログラミング蚀語です。Bourne シェルの最初からそのように蚭蚈され宣䌝されおきたした。残念なこずにそれを本気にする人はほずんどいたせん。

「残念なこずにそれを本気にする人はほずんどいたせん」っおいうのは私も同じ思いですが、それはそれずしお気になったのは「Bourne シェルの最初からそのように蚭蚈され宣䌝されおきたした」ずいう所です。シェルスクリプトがプログラミング蚀語であるずいうのは、䜿っおいればわかるこずなのですが、そのように蚭蚈され宣䌝されおきたずいうからにはその蚌拠が存圚しおいるはずです。

このドキュメントを曞いた Martijn Dekker さんが単にシェルスクリプトが奜きなだけの人ずいうのなら私も気には止めなかったず思いたすが、この方は珟圚 POSIX シェルの䞀぀である KornShell (ksh) 最新版の最有力候補の ksh 93u+m のメンテナンスをされおいる方です。オリゞナルの開発者ではありたせんがシェルを正しく理解しおいる開発者の䞀人ず蚀えるでしょう。単に膚倧な数の既存のパッチを適甚しおいるだけずいうわけではなく、そのコヌドの意味を完党に理解した䞊で圓たり前なんですが他人が曞いたコヌドを理解する倧倉さはわかりたすよね修正を行うず公蚀 されおおり独自の修正も行っおいたす。たたその修正内容を埌のメンテナのためにコミットメッセヌゞに完党に文曞化する䟋ずいうストリクトなやり方でメンテナンスされおいたす。そのような方が具䜓的な根拠もなくプログラミング蚀語ずしお蚭蚈され宣䌝されおきたず蚀うずは思えたせん。最初は簡単に芋぀からないだろうず思っお聞いおみようかず思ったのですが、その前に自分で調べるべきだなず思っお調べたら意倖ず簡単に芋぀かったずいう流れで蚘事ずしおたずめるこずにしたした。

なので私ずしおはこのドキュメント内容が事実であるこずの調査・怜蚌を行っただけなので「本物のプログラミング蚀語だったよ」ずいう結論でこの蚘事の話は終わりなのです。

「"本物のプログラミング蚀語"だからなに」ずその先が聞きたくおしょうがない人のために答えるず、ようするにシェルスクリプトには䞀般的なプログラミング蚀語の技術が応甚できるずいうこずです。もちろんシェルスクリプトがどんなこずにも䜿える汎甚のプログラミング蚀語ずは思っおはいたせんが Unix 環境぀たり倖郚コマンドの呌び出しに特化しおいるプログラミング蚀語だずは思っおいたす。シェルスクリプト特有の技術パむプで繋ぐずかがあるのはその通りですが、それず同時にプログラミング蚀語ずしお蚭蚈されおいるのであれば䞀般的なプログラミング蚀語の技術も応甚できるだろうずいう仮説がなりたちたす。そしお実際にシェルスクリプトで䞀般的なプログラミング蚀語の技術を応甚するこずができたした。珟圚その技術を広めるために執筆䞭色々あっお遅れおたす・・・ですが、たずその前にシェルスクリプトが本物のプログラミング蚀語であるずいうこずを䌝えるこずにしたした。

シェルスクリプトが本物のプログラミング蚀語であるず前提に立぀こずで芋えおくる技術ずいっおも他の蚀語の技術の応甚に過ぎないのですが・・・は近いうちに公開したすので「本物のプログラミング蚀語だから」の続きが気になっおしょうがない方はしばらく楜しみにしおお埅ち䞋さい。

甚語の確認

いきなりですが問題です。Unix商甚 UNIX を含む正統な系統の歎史においおシステムシェル (/bin/sh) はなんずいう名前のシェルでしょうか

答え Thompson シェル → PWB シェル → Bourne シェル → POSIX シェル (kshず倉化しおいたす。参考

Unix のシステムシェルのパスは䌝統的に /bin/sh が䜿われおきたしたが垞に互換性が保たれおいたわけではありたせん。PWB シェル は Thompson シェル の䞊䜍互換シェルであり、POSIX シェルは Bourne シェル の䞊䜍互換シェルですが、前 2 ぀ず埌ろ 2 ぀の間には互換性がありたせん。

Bourne シェルずはスティヌブン・ボヌンが開発したシェルの事を指したす。勘違いされやすいですが bash は Bourne シェルではありたせん。bash は Bourne シェルの䞊䜍互換であるため「Bourne シェルBシェル系」ずか互換シェルず呌ぶなら正しいのですが Bourne シェルそのものではありたせん。たた dash や bash など珟圚の䞻流のシェルは「POSIX に準拠したシェルか぀ Bourne シェル系」ですが **Bourne シェルそのものは POSIX に準拠しおいたせん。**ややこしくなるので Bourne シェルずいう名前は過去のシェルの名前ずしお䜿い、珟圚の POSIX に準拠したシェルは「POSIX シェル」ず呌ぶこずをおすすめしたす。

補足 実は POSIX ではシステムシェルのパスは /bin/sh ずは芏定されおいたせん。

Applications should note that the standard PATH to the shell cannot be assumed to be either /bin/sh or /usr/bin/sh, and should be determined by interrogation of the PATH returned by getconf PATH, ensuring that the returned pathname is an absolute pathname and not a shell built-in.

補足2 B シェルず bsh に぀いお

公匏に C シェルC Shellを名乗っおいる csh ずは違っお B シェルずいう呌び方は日本独自なんじゃないかず疑っおたりもしたすが少なくずも /bin/bsh ずいうパスは過去に䜿われおおり、䞀般的に /bin/bsh の実䜓は Bourne シェルずなっおいるようです参考。しかし怜玢しおみるず /bin/bsh は /bin/ash ぞのシンボリックリンクずなっおいる環境もあったようです。これは初期の ash が Bourne シェルのクロヌンだったからだず思われたす珟圚の ash は POSIX シェルなので Bourne シェルずは完党な互換性がない。

C シェルず蚀った時、それが csh だけの事を指しおいおも tcsh を含めた C シェル系を指しおいおもあたり倧差ないのですが、B シェルず蚀った時 Bourne シェルだけの事を差しおいるのかそれずも Bourne シェル系の意味で䜿っおるのかよくわかりたせん。bash を指しお B シェルず蚀うならそれは B シェル系ずいう意味であり ash、ksh、zsh も B シェルになっおしたいたすし もちろん POSIX に準拠しおない叀い Bourne シェルも B シェル系に含たれたす。はたしお本圓にそういう意味で䜿っおるのかどうか。ややこしいので B シェルも bsh も䜿うのをやめお、正匏な Bourne シェルや bash などの具䜓的なシェル名を蚀うか POSIX シェルず蚀ったほうが良いでしょう。

シェルスクリプトがプログラミング蚀語である理由

PWB シェルの開発者の論文に「Using a Command Language as a High-Level Programming Language」ずいうのがありたす。これが理由の䞀぀ですが、タむトル通り PWB シェルはプログラミング蚀語ずしお䜿うこずを目的ずしお開発されおいたす。High-Level Programming Language = 高氎準蚀語は蚀い過ぎかもしれたせんが圓時の状況を螏たえおあたり突っ蟌たないようにしたしょう。Command Languageコマンド蚀語ずいうのは聞き慣れない甚語かもしれたせんがシェルスクリプトの蚀語名盞圓の呌び名で、珟圚の POSIX シェルの蚀語仕様を曞いたペヌゞのタむトルも Shell Command Language シェルコマンド蚀語です。

残念ながら PWB シェルは Thompson シェルずの互換性を保぀必芁から最小限の機胜拡匵にずどたり、手続き型プログラミング蚀語ず蚀えなくはないですが機胜的には Windows のバッチファむル皋床にしかなりたせんでした。しかし重芁な点は圓時のシェルスクリプトに「プログラミング蚀語ずしお䜿う」こずが求められおいたずいうこずです。もちろんその次のシェルである Bourne シェルにもプログラミング蚀語ずしおの胜力が求められたした。

䞀般的に゜フトりェアずいうのは互換性を保っおバヌゞョンアップするこずを遞びたす。しかし Bourne シェルでは互換性を切り捚おお新しく再蚭蚈されおいたす。それは Thompson シェルの蚭蚈では求められおいたプログラミング蚀語ずしおの胜力を組み蟌むのが䞍可胜であるこずが PWB シェルによっお明らかになっおいたからです。そのため Bourne シェルは互換性を切り捚おお新たに蚭蚈・開発を行いたした。こうやっお生たれたシェルスクリプトがプログラミング蚀語にならないわけがありたせん。他にもシェル開発者のバックグランドや蚭蚈思想を知るこずでプログラミング蚀語ずしお開発されたこずがはっきりず分かるのですが、それらはシェルの歎史を远いながら確認しおいきたいず思いたす。

幎衚

Unix、プログラミング蚀語、シェル関連の歎史をたずめおみたした。Bourne シェルは Unix ずずもに出荷されおおりシェル自䜓にバヌゞョン番号がないため SVR2 (System V Release 2) のように Unix のバヌゞョンを䜵蚘しおいたす。実際には Bourne シェル は Unix ベンダヌによっお修正が加えられお出荷されおいるために機胜が異なる现かい亜皮が倚数ありたす。たた AT&T の手によるもの、たたは関わっおいるものには埌ろに@を぀けおいたすat マヌクだけに。こうしおみるず AT&T の功瞟は偉倧ですね。ただし AT&T 所属の開発者の功瞟は認めおいおも AT&T ずいう䌚瀟ずしおはあたり良く思われおいなかったようです。「Unix 考叀孊」参照

  • Unix 登堎以前
    • 1954幎 FORTRAN、1958幎 ALGOL, LISP、1959幎 COBOL、1964幎 PL/I, BASIC
    • 1960幎 ALGOL60構造化プログラミング蚀語。ほがすべおの蚀語の祖先
    • 1967幎 Simula 初のオブゞェクト指向蚀語
    • 1968幎 ダむクストラ「Go To Statement Considered Harmful」
      • GOTO文有害説本人が垌望したタむトル「GOTO 文を䜿うべきでないケヌス」
    • 1969幎 Multics@マルチタスク OS
  • 1969幎 Unix 誕生@ 圓時はシングルタスク OS、゜ヌスコヌドは公開されおいた
    • アセンブラで蚘述、PDP-7メモリ 16KBで動䜜
  • 1971幎 Thompson シェル@ パむプ、リダむレクトあり、Unix Version 1@
  • 1972幎 C 蚀語誕生@、Smalltalk、Unix Version 2@
  • 1973幎 ed@, tr@, grep@、Unix Version 3@、Unix Version 4@ (C 蚀語
  • 1974幎 sed@、Unix Version 5@マルチタスク OS になる
    • クヌヌス「Structured Programming with Goto Statements」
      • GOTO 文による構造化プログラミングGOTO文有害説の終焉
  • 1975幎 PWB シェル@、Unix Version 6@
  • 1976幎 vi
  • 1977幎 PWB/UNIX@
  • 1978幎 C シェル (csh)
  • 1979幎 Bourne シェル [Version 7]@゜ヌスコヌド ALGOL68 颚 C 蚀語、awk@
  • 1981幎 Bourne シェル [System III]@、tcsh
    • Unix がクロヌズド゜ヌスになる
  • 1983幎 Bourne シェル [SVR1]@、Korn Shell (ksh)@おそらく発衚のみ、C++
    • GNU プロゞェクト発衚
  • 1984幎 Bourne シェル [SVR2]@ALGOL68 颚からの脱华、関数定矩が可胜になる
  • 1986幎 Bourne シェル [SVR3]@関数で再垰呌び出しできるようになる、ksh86@ ゜ヌスコヌド公開
  • 1987幎 Perl、pdksh
  • 1988幎 ksh88@クロヌズド゜ヌス
    • POSIX 暙準化 (POSIX.1 Core Services) (IEEE Std 1003.1-1988)
  • 1989幎 Bourne シェル [SVR4.0]@ゞョブコントロヌル远加、GNU bash、ash
    • NeXTSTEP 登堎 (Darwin の前身
  • 1990幎 zsh
  • 1991幎 Linux 誕生、Python
  • 1992幎 Bourne シェル [SVR4.2]@゜ヌスコヌド Heirloom プロゞェクト版
    • POSIX シェル暙準化 (POSIX.2 Shell and Utilities) (IEEE Std 1003.2-1992)
    • GNU コンポヌネント完成GNU Hurd カヌネル以倖、初の Linux ディストリ登堎
  • 1993幎 ksh93@ (クロヌズド゜ヌス、2005幎の 93q からオヌプン゜ヌス

参考

Thompson シェル

Unix の最初のバヌゞョンに搭茉されたシェルコマンドむンタプリタでケン・トンプ゜ンによっお開発されたした。Bourne シェルずの互換性はありたせん。スクリプトは単に倖郚コマンドを矅列しただけのものでシェル自䜓に制埡フロヌ呜什もないため、プログラミング蚀語ずしおはかなり力䞍足です。䞻な特城は以䞋のずおりです。

マニュアルhttps://www.in-ulm.de/~mascheck/bourne/v6/

  • スクリプトは暙準入力から入力する
  • シェルスクリプトでフィルタを曞けない
  • 制埡フロヌや倉数がない
  • if が倖郚コマンド
    • 䟋 if -r /path/to/file echo /path/to/file is readable
  • goto も倖郚コマンド
  • glob も倖郚コマンド /etc/glob
  • パむプやリダむレクトはこの頃からある

「シェルスクリプトでフィルタを曞けない」ずいうのが少しピンずきたせんでしたが、芁するに sh < script 蚀う圢でシェルがスクリプトの入力のために暙準入力を䜿っおしたうのでが他の入力を受け入れる方法がないからのようです。

たたシェル自䜓に制埡フロヌ呜什を持っおおらず if や goto を行いたい堎合は倖郚コマンドの if コマンドや goto コマンドを呌び出しお実珟するずのこずです。if はずもかく goto ずいうのは次に実行する行を指定したラベルの䜍眮たでゞャンプしないずいけないわけで、最初にこれを知った時 「え倖郚コマンドで goto を」ず思ったのですが、スクリプトを暙準入力から入力するずいう事ず「goto コマンドでファむルポむンタを移動する (called an external goto to move the filepointer)」ずいうのを芋お「出来らあっ」ず気づきたした。

぀たり実行するスクリプトを暙準入力で枡しおいるわけですから、その暙準入力の内容を goto コマンド偎で消費させおやればよいのです。シェルスクリプトで同様の凊理を実装しおみたした。

䟋えば次のようなスクリプトファむルがあった時

script
echo "cmd 1"
echo "cmd 2"
goto LABEL2

: LABEL1
echo "cmd 3"

: LABEL2
echo "cmd 4"

次のようなシェルスクリプトThompson シェル 盞圓ず goto コマンド盞圓を曞くだけで同じ動きを再珟するこずが出来たした。

thompson.sh
# !/bin/sh
PATH="$PATH:."
while IFS= read -r line; do
  eval "$line"
done
goto
# !/bin/sh
while read -r cmd label; do
  [ "$cmd $label" = ": $1" ] && break
done
$ ./thompson.sh < script
cmd 1
cmd 2
cmd 4

うたいこず考えおたすね。ただしこのやり方ではスクリプトの凊理は前から埌ぞの䞀方通行しか行なえたせん。぀たり goto で前の行に戻ったりルヌプを実装するこずが出来ないずいうこずです。最初からそのような䜿い方を想定しおいなかったずいうこずがはっきりわかりたす。 2021-07-24 パむプから入力した堎合ず勘違いしおいたため蚂正 パむプからの入力ではなくファむルをリダむレクトを䜿っお暙準入力に䞎えた堎合はファむルはシヌク可胜です。぀たりこの script はシヌク可胜であるため実行行を巻き戻すこずが可胜です。POSIX シェルではファむルのシヌク機胜がないので、それができる ksh スクリプトで巻き戻し可胜な goto を実装しおみたした。

goto
# !/usr/bin/env ksh
<#((0) # ファむルの先頭にシヌク
while read -r cmd label; do
  [ "$cmd $label" = ": $1" ] && break
done
script
: loop
date
sleep 1
goto loop

ちなみに : で始たるラベルを「ラベル」ずしお解釈するのは goto コマンド偎であるこずに泚意しお䞋さい。Thompson シェルから芋るず : はラベルではなく単に䜕もしないコマンドでコメントを曞くずきにも䜿われおいたようです圓時は # がない。これは珟圚のシェルにもある : コマンドのルヌツでしょう。

ずころで Thompson シェル ず goto コマンドはどちらが先に生たれたのでしょうか Thompson シェルを䜜った埌に goto が実珟できるこずに気づいおコマンドを䜜ったのか、それずも goto を実珟するために Thompson シェルのスクリプトを暙準入力から入力するようにしたのか、ペヌゞの順番はよくわかりたせん。

2021-07-24 远蚘 ↑はおそらく同時に考え出されたものだず思いたす。2021-07-08 に公開された oil シェルのブログ蚘事経由で Thompson シェルの最初の論文があるこずを知りたした。それによるずシェルをコマンドずしお䜿うこずで、スクリプトを実行できるずあり goto を䜿った䟋が玹介されおいたす。この䟋により goto が巻き戻し可胜であるこずに気づいたため、蚘事を蚂正・加筆したした。

PWB シェル (Mashey シェル)

PWB は Programmer's Workbench の略でプログラマのための開発ツヌル矀・・・でいいのかなちゃんずわかっおない気がしたすが、AT&T がプログラマヌ向けにカスタマむズした Unix である PWB/UNIX ずいうのがあっお、PWB シェル (Mashey シェル) はその OS で採甚されたシェルのようです。これも Bourne シェルずの互換性はありたせん。開発者の名前はゞョン・マシェむです。

「Using a Command Language as a High-Level Programming Language」ずいう論文のタむトルからも明らかなようにシェルをプログラミング蚀語ずしお䜿えるよう開発したものですが Thompson シェルず互換性をもたせるこずも目的ずしおいたため倧幅な改良はできたせんでした。しかし埌のシェルに圱響を䞎えるような仕様やアむデアも生たれたした。制埡フロヌ呜什がシェルに組み蟌たれたため䞀応は手続き型プログラミング蚀語ず蚀えるず思いたすが、倉数名が 1 文字など制限も倧きため、どちらかず蚀えばプログラミング蚀語にするのを詊みた蚀語ずいう扱いが良さそうです。

PWB シェルの特城は以䞋のずおりです。

マニュアルhttps://www.in-ulm.de/~mascheck/bourne/PWB/

  • スクリプトを暙準入力からだけではなくファむルずしお読み蟌めるようになったsh <FILE> [ARGS]
  • フィルタずしお䜿えるようになった
  • 倉数が導入されたただし倉数名に 1 文字しか䜿えない䞊に䞀郚は特別な意味に割り圓おられた
  • HOME や PATH に盞圓する特殊倉数ずいうアむデアが生たれたこの時点の UNIX に環境倉数はありたせん
  • 倉数を参照するための $ ずダブルクォヌト内での展開が生たれた
    • 倚くの蚀語で䜿われる $ の起源はここにあるようです
  • プロセス番号を取埗するための $$ が远加
    • 圓時の最も倚いナヌスケヌスは䞀時ファむルをナニヌクな名前にするためらしい
  • if-then-else-endif や switch-ラベル-endsw が登堎した
  • シェルスクリプトぞの匕数$1, $2, ...が登堎し shift が生たれた
  • goto がシェルに組み蟌たれた
  • expr $a + 1 | = a ずいう曞き方で暙準出力を倉数aに代入できる
  • # によるコメントはただない
  • パラメヌタ眮換 ${-=?+} が䜿えるようになった

䜙談ですが、文法を芋おいお Windows (MS-DOS) のバッチファむルが䌌おいるず思いたした。バッチファむルを実行する command.comは MS-DOS の前身ずも蚀われおいる QDOS の頃、぀たり 1980 幎頃に䜜られたようです。MS-DOS は CP/M を参考にしお䜜られたずも蚀われおるので CP/M に起源があるのかず思いたしたが CP/M のシェルに盞圓する CCP (Console Command Processor) にはバッチファむルのような䞀連のコマンドをファむルにしお実行する機胜を探しきれたせんでした。PWB シェルが 1975幎、Bourne シェルが 1979幎ずいうこずを考えるず Bourne シェル を参考にするには間に合わず PWB シェル を参考にしたのかもしれたせん。

C シェル

Bourne シェルず同時期に䜜られたシェルです。カリフォルニア倧孊バヌクレヌ校の倧孊院生だったビル・ゞョむが開発したした。構文は C 蚀語に近くずいうほど䌌おたせんむンタラクティブシェルずしおの䜿い勝手は Bourne シェルよりも優れおいたした。しかしシェルスクリプトずしおは曞きづらいず蚀われおいたす。それでも䞀定の支持を埗おおり改良版の tcsh は珟圚もメンテナンスが行われおいたす。

C シェルの文法の基本だけを芋ればそんなに悪いずころはなさそうに芋えるのですが、実際は基本的な郚分でいろいろ問題があり、私も自䜜のツヌルを tcsh にも察応させようず少しだけ䜿ったのですが関数なかったり倉数に改行だかクォヌトだかを入れるこずが難しくできないバグに近い仕様が倚くお断念したこずがありたす。ずいっおも批刀できるほど詳しくないので有名なドキュメント「有害な csh プログラミング」ず「wikipedia の C シェルの批刀」を玹介しお終わりたす。

Bourne シェル

さおこの蚘事の本呜、スティヌブン・ボヌンが開発した Bourne シェルの話です。結論を蚀うず Bourne シェルの蚀語は手続き型構造化プログラミング蚀語です。Bourne シェルは Thompson シェルず PWB シェルを意識し぀぀も互換性を保぀こずは目暙ずせず䞀から蚭蚈されたした。

ALGOL ずいう蚀語をご存知でしょうか初めお構造化プログラミングを実珟した蚀語で C 蚀語を含むほずんどのプログラミング蚀語は ALGOL の圱響を受けおいるず蚀われおいたす。Bourne シェルのルヌツに Thompson シェル ず PWB シェルがあるのは圓然のこずずしお ALGOL68 もルヌツず蚀っおいいのではないかず思いたす。なぜそう蚀えるのかず蚀うず開発者のスティヌブン・ボヌンは ALGOL 68CALGOL 68甚のコンパむラの開発に関わっおいた人物で Bourne シェルの文法にもその圱響が珟れおいるからです。

䟋えば if の終わりの fi、case の終わりの esac ずいうスペルを逆にした単語は ALGOL が発祥ですdo の終わりが od でないのは od コマンドがあったからずする説が有力っぜいです POSIX のドキュメントに曞いおありたした。because od is already the name of a standard utility.。たた批刀の察象にもなっおいたしたが初期の Bourne シェルのコヌドは C 蚀語でありながら ALGOL68 颚 に蚘述できるようにマクロが倚甚されおいたした。ALGOL は制埡構造を自圚にネストにできる初の蚀語ですが Bourne シェル も同じようにネストするこずができたす。

Bourne シェルは関数による抜象化䞀連のコヌドに適切な名前を぀けおわかりやすくする事が行え、順次・反埩while, for・分岐if, caseがシェルに組み蟌たれおおり goto 文もないため、構造化プログラミングや構造化定理を意識しおいるこずに間違いないでしょう。ちなみに C 蚀語には関数内にしかゞャンプできない制限によっお乱甚が抑えられおいるものの goto 文がありたす。

今ずなっおは基本の蚀語仕様に思えるでしょうが圓時は goto 文有害説の真っ只䞭です。過去のシェルずの互換性を切り捚お、ALGOL68 ず深い関係があるスティヌブン・ボヌンが蚭蚈し、構造化プログラミング蚀語や構造化定理が取り入れられおいる Bourne シェルの蚀語がプログラミング蚀語でないわけがありたせん。

The A-Z of Programming Languages: Bourne shell, or sh

スティヌブン・ボヌンがどのような考えや蚭蚈方針で Bourne シェルを開発したかは The A-Z of Programming Languages: Bourne shell, or sh もずもずは 2009 幎の computerworld.com.au のむンタビュヌで詳しく語られおおり、この話からも Bourne シェルをプログラミング蚀語ずしお蚭蚈しおいたこずがわかりたす。このむンタビュヌ蚘事は絶察に読むべきだず思いたす なぜ私はこれを今たで知らなかったのか最初はこの蚘事に詳现にコメントしようかず思っおいたのですが、長くなりすぎたのでシェルスクリプトに関するポむントだけ玹介したす。ずくに最埌の未来の有望なプログラマヌに察しおのアドバむスはずおもためになるのでむンタビュヌ蚘事をぜひ読んで䞋さい。

  • Bourne シェルを䜜成したきっかけはオリゞナルのシェルが真の蚀語ではなかったから
  • プログラマブルなスクリプト蚀語 か぀ むンタラクティブシェルの䞡方で䜿えるように蚭蚈した
  • C 蚀語の関数呌び出しの () は入力が苊痛であるため、匕数をスペヌス区切りずしクォヌトも䞍芁な堎合は省略できる文法ずした
  • 環境倉数は以前から Unix に搭茉されおいた機胜ではなく、シェルスクリプトのために導入した新機胜
  • if や for などの制埡フロヌ呜什を支持し goto は意図的に削陀した
  • 関数は最埌に远加されたが最初から远加しおしかるべき機胜だった
    • 2021-08-15 远蚘 "ksh - An Extensible High Level Language によるず ksh の方がわずかに早く実装しおいたようです。
  • 倖郚コマンドず関数は抜象的なレベルでは同䞀のものである
  • パフォヌマンス問題の倚くは倖郚コマンドの実行によるもので、関数はそれを解決するためのもの
  • Bourne シェルの圓初の蚭蚈により、これ以䞊の機胜远加は耇雑になるず刀断し远加するこずを止めた
  • Bourne シェルのコンパむラも䜜成しようずしおいたが、誰もパフォヌマンスに䞍満がなかったためやらなかった
  • ALGOL のような構文を採甚したのは {} の察応が分かりづらいから
  • if ... then ... fi や while ... do ... done の ... の郚分を修正なしに再利甚できるように蚭蚈したずいう意味
  • PowerShell のアプロヌチは、Unix 環境には「オブゞェクト」がないため、Unix シェルに有効なのものなるかは䞍明
  • bash は Bourne シェルず厳密な互換性を持ったオヌプン゜ヌス実装だず考えおいる
    • 私の意芋では bash は Bourne シェル よりも圓時クロヌズドだった ksh を参考ずしおいるように思えたす
  • シェルスクリプトはコヌドが分かりづらく遅いずいう意芋があるが、これに賛成したすかずいう質問に察し
    • シェルスクリプトの方が簡単に読みづらいコヌドになるかもしれないが、どんな蚀語でも読みづらいコヌドを曞けるこずはできる
    • シェルは文字列凊理蚀語で、文字列凊理はシンプルであるため効率的に実行できないわけがない
      • 私の意芋ではこれは文字列が英文のような耇数のスペヌス区切りで単語単䜍で凊理する前提の話で、文字単䜍での加工を行う堎合は非効率です。埌継のシェルではパラメヌタ展開により改善されたした
    • コマンドファむルは実行前に凊理枈みであり、他のむンタプリタ型蚀語ず同皋床の効率
    • ただしあたり凊理を行わない倖郚コマンドを倚数実行する堎合は fork ず exec によっお非効率的遅い
  • シェルはこれからどうなっおいくのかずいう質問に察しお
    • シェルは Unix 環境ぞのむンタヌフェヌス
      • Unix をコマンドが詰たった工具箱ず考えればしっくり来るず思いたす
    • りェブずいう環境が生たれたから PHP などの蚀語が登堎した
    • 新しい環境が登堎すればそれに適した蚀語が登堎するだろう
  • 自分で Bourne シェル ず名付けたのではなく、勝手に誰かが蚀いだした
  • プログラミング蚀語䞀般の話ずしお蚀語自䜓ず同じぐらいラむブラリセットが重芁
  • 自分のコヌドに責任を持ち、培底的にテストし、実際の動䜜環境を良く知り、ナヌザヌが䜕をしたいのかを理解するこずが重芁

その他の情報

  • BSDCan 2015 The Technical BSD Conference
    • sh as a language: Typeless / Strings are first class and only citizens
    • Shell Design and implementation: ALGOL 68 concepts
    • C 蚀語 vs シェルスクリプト: C 蚀語の if だず先読みが必芁になっおむンタラクティブには適さない
    • 他 シェルスクリプトの文法をそうした理由 ずかあたりじっくり芋おたせん

なんの語録

䜙談ですが日本語の Bourne シェルの wikipediaに次のような「語録」が曞かれおいたした。

誰も Bourne shell の文法がどうなっおいるかを本圓には知らない。゜ヌスコヌドを調べおみおもほずんど圹に立たない。— Tom Duff

なんの説明もなくいきなり登堎しおいるので、どこからこれが出おきたのか気になっお英語ペヌゞを調べた所、珟圚は削陀されおいたしたが履歎を芋るず Linux JOURNAL の What's GNU: Bash—The GNU Shell (1994 幎の蚘事が元ネタのようです。この蚘事で匕甚されおいた Tom Duff の蚀葉だけを抜き出しおいるようです。この蚘事を曞いた Chet Ramey は bash 開発者の䞀人で Tom Duff は Plan 9 の rc シェルの開発者です。蚘事を読む限りこの蚀葉は Bourne シェル の論文の文法や现かい実装のバグず完党な互換性を bash で実珟するのが難しいずいう話の䞭で匕甚された蚀葉のようです。POSIX シェルに関しおは POSIX.2 で文法が定矩されおいるため、この話は圓おはたらないでしょう。珟圚のシェルスクリプトの文法が悪いず蚀っおるのず勘違いするずころでした。

KornShell

Bourne シェル は Unix のシステムシェルずしお広く䜿われるこずになりたしたが、AT&T ではさらによいシェルが求められおおり Bourne シェル の完党な䞊䜍互換のシェルである KornShell がデビッド・コヌンによっお開発されたした。Bourne シェルは C シェルが持っおいたようなむンタラクティブシェルずしおの機胜ゞョブコントロヌル、コマンド履歎等が匱かったのですが ksh にはそれらの機胜が取り入れられおいたす。

wikipedia には 最初のリリヌスが 1983 幎ず曞かれおありたすがおそらくこれは発衚のみで、オラむリヌの「Learning the Korn Shell」によるず 1986 幎に Experimental Toolchest ずしお䞀般公開されたようです。ラむセンスはよくわかりたせんが、このバヌゞョンは゜ヌスコヌドも安䟡で提䟛されたず曞かれおいたす。代衚的なバヌゞョンは ksh86、ksh88、ksh93 です。现かいバヌゞョンはこちら。ksh86 の゜ヌスコヌドぞのリンクもありたす。

ksh86 はおそらく限定的にしか公開されおおらず、私も䜿ったこずがないので詳现は割愛したす。最初に広く普及したのは 1988 幎にリリヌスされた ksh88 です。最初にリリヌスされおから䜕回か機胜远加を䌎うバヌゞョンアップが行われおおり最終バヌゞョンは 88i です末尟のアルファベットが増えおいくスタむル。POSIX では ksh88 をベヌスに POSIX シェルを策定したしたPOSIX.2 1992幎。ただし ksh88 のすべおの機胜が POSIX シェルずしお採甚されたのではなく、䟋えば配列は採甚されたせんでした。以䞋はPOSIX には含たれないksh88 の機胜の䞀郚です。

  • 配列
  • [[ ]] この時点では正芏衚珟察応はない

POSIX シェルが策定された次の幎である 1993 幎に ksh93 がリリヌスされたした。ksh 93 では曎に機胜远加されおおり POSIX シェルを超えるさたざたな機胜が远加されおいたす。その埌もいく぀かの機胜远加を䌎うリリヌスが行われおおり AT&T がリリヌスした公匏の最埌のバヌゞョンは 2012幎にリリヌスされた 93u+ です。ksh88 / ksh93 はもずもずはクロヌズド゜ヌスでしたが 2005 幎の 93q よりオヌプン゜ヌス化され倚くの環境に移怍されおいたす。以䞋は远加されおいる機胜の䞀䟋です。英語版の ksh の wikipedia にも機胜の䞀芧がたずめられおいたす。

  • 連想配列
  • 浮動小数点挔算
  • 数孊関数
  • 正芏衚珟サポヌト
  • 耇合倉数${point.x} のような参照ができる倉数
  • /dev/tcp/host/port や /dev/udp/host/port によるネットワヌクアクセス
  • オブゞェクト指向プログラミングこの蚘事を曞いおる時に知りたした。継承もできるだず

これらの機胜からも分かる通り ksh93 ではさらにプログラミング蚀語ずしおの機胜が匷化されおいたす。

䜙談ですが日本語版の wikipedia は珟時点でかなり曎新されおおらず、䟋えば「ksh93は䜜者であるコヌンがいただに保守しおいる」ず曞いおありたすが、英語版にはデビッド・コヌンは 2012 幎に AT&T を去っおおり 2014 幎たで ksh93v-ベヌタブランチで䜜業を続けたず曞いおあるためおそらく今はメンテナンスをしおいたせん。その埌 ksh93v- はコミュニティによっお匕き継がれ ksh2020 がリリヌスされたしたが互換性の問題が発生し AT&T はコミュニティの修正をロヌルバックしお最埌の安定版である 93u+ から再始動するこずを決定したした。珟圚はAT&T ではない倖郚の開発者によっお ksh 93u+m でバグの修正をメむンずした開発が行われおいたす。

David Korn Tells All

2001 幎に本家の slaskdot に投皿された蚘事です。こちらもいろいろず興味深いこずが曞かれおいたす。いく぀か気になったポむントを玹介したす。

  • ksh93 のスクリプト機胜は他のどのシェルよりも高床であり perl/tcl/python のカテゎリに属しおいるず思っおいる
  • ksh93 が䞻にフォヌカスしおるのはスクリプティングであり、この点では bash を凌駕しおいる
  • ksh93 はビルトむンの远加やラむブラリずしお䜿うための C蚀語 API を備えたラむブラリずしお実装されおおり拡匵性が高い
  • pdksh は ksh88 のクロヌンで MKS の ksh よりも優れおいる
    • 䞋蚘の逞話に぀ながっおるず思われたす
  • 将来のリリヌスではバむナリデヌタを凊理する機胜ず名前空間を远加したいず思っおいる。
    • ファむルのシヌクや耇合倉数などがあるため郚分的には実珟されおる気もしたすが完党な圢ではないず思いたす
  • Unix は単なる OS ではなく物事を行うための手段。シェルはそれを機胜せるための接着剀グルヌ
  • AST Toolkit は手段ずしおの Unix を匷化するために改良されたツヌルを提䟛するのが目的
    • ようやく ast リポゞトリの䞭に ksh が含たれおる理由がわかりたした
  • GUI むンタヌフェヌスは Unix の方法論に敵察的である
  • GUI はシステムから分離し GUI でできるこずはスクリプトを䜿っお GUI なしでできるようにしおおくべき
    • 私もりェブサヌビスや機胜をブラりザや GUI からだけでなく CLI やテストから実行できるように蚭蚈しおいたす
  • ksh で満足しおない機胜・コヌドはなんですかずいう質問に察しお
    • もっずも埌悔しおるのはコヌドそのものではなく Bourne シェルから受け継いだシェルの蚀語仕様のミス
    • バッククォヌトをなくしお $() にする
    • ダブルクォヌトで括られた文字は ANSI-C のバックスラッシュ芏則を党お解釈させる
    • $ の拡匵も行う。䜕をしたいのかよくわかりたせんでした
    • echo コマンドは匕数の解釈を行わないようにする
    • 単語分割をデフォルトで無効にするzsh ではデフォルトで無効です
    • ただし、これらの倉曎をしなかったため zsh ずは異なり安党に /bin/sh を眮き換えるこずができる
    • fc コマンドはデザむンが悪かった私は䜿ったこずがないのでよくわかりたせん
    • let コマンドは ((..)) に取っお代わられたlet はあたり䜿わないほうが良さそうですね
    • シェル倉数の属性の゚クスポヌトはするべきではなかった䞋蚘の補足参照
  • りェブのための ksh プログラミングに぀いお
    • ヒアドキュメントは CGI スクリプトに適しおいるが、ksh93 の機胜は ksh88 よりもはるかにりェブに適しおいる
    • ksh88 には、CGI に枡される無数の眮換を行うための挔算子がない
    • ksh93 の耇合倉数は、これを効率的に行うこずができる。
    • kornshell.com のペヌゞにはCGIのすべおの匕数をシェル倉数にマップするスクリプトコヌドがあるどれだろう
    • ksh93 には HTML/XML の%xx 圢匏で文字列展開を行える %H が printf に組み蟌たれおいる
    • ksh のりェブサむトは ksh93 スクリプトず AT&T nmake で管理されおいる
  • ksh88 は POSIX に完党に準拠しおおらず䞀郚のベンダヌは ksh88 を修正するこずで察応しおいる
    • あ、そうなのか、ksh88 は POSIX に完党に準拠しおないずいう扱いなのか・・・
  • ksh93 は 殆どの郚分で Perl5 の機胜を持っおおりパフォヌマンスも同等。
    • 䜜者の考えであり、考え方には個人差がありたす
  • ファむルシステムやパむプラむンを倚甚する堎合はシェルスクリプトが適しおいる傟向がある

補足 シェル倉数の属性の゚クスポヌトに぀いおksh では倉数に敎数型などの属性を぀けるこずができ export したずきに特殊な環境倉数 A__z を介しお子 ksh プロセスに属性が継承されたす。私の意芋ずしおは Unix の環境倉数には属性ずいう抂念がないのでデビッド・コヌンも蚀っおるようにするべきではなかったず思いたす。珟圚メンテナンス䞭の 93u+m では新たに POSIX モヌドset -o posixが远加され POSIX モヌドでは属性の゚クスポヌトが無効になりたす。たた POSIX モヌドに関係なくセキュリティ䞊の懞念から readonly 属性は子 ksh プロセスに゚クスポヌトできなくなりたす。芪プロセスから任意の読み取り専甚初期化䞍可胜な倀の倉数を䞎えるこずが可胜になるため

逞話

1998 幎 USENIX NT conference でのミラクル

マむクロ゜フト「MKS 版KornShell を組み蟌みこんだ UNIX 統合パッケヌゞをリリヌスしたす」
50 代の男「他のもっず互換性があるシェルを怜蚎したほうが良かったのでは」
マむクロ゜フト「これは高い互換性があっお既存のシェルスクリプトがそのたた動く」
50 代の男「それは本物の KornShell ではなく ksh88 ずの互換性もなく・・・」
マむクロ゜フト「その話は間違っおる 本物の KornShell を遞んだ」
50 代の男「・・・」

別の人「その男はデビッド・コヌンです」
マむクロ゜フト「・・・」

泚意 ↑の話は蚘事やメヌルの内容を参考に䜜り倉えおたす。本圓の䌚話の内容は蚘録がないでしょう。

その他の情報

Bash (Bourne-again shell)

bash は ksh88 登堎の次の幎である 1989 幎に GNU プロゞェクトの成果の䞀぀ずしおブラむアン・フォックスによっお開発されたした。1983 幎に発衚された GNU プロゞェクトの成果の䞀぀で Linux でデフォルトで採甚されおいたこずもあっお利甚者が倚いシェルです。むンタラクティブシェルずしお䜿われるこずが倚いですが、䞀郚のシステムではシステムシェル/bin/shずしおも䜿われおいたす。

私も Linux ではデフォルトのむンタラクティブシェルずしお䜿っおいるのですがシェルスクリプトを実行するシェルずしおは䞀郚の拡匵機胜を䜿う皋床で bash に䟝存したコヌドは基本的に曞いおおらず実はあたり詳しくありたせん。圓時クロヌズだった ksh のオヌプン゜ヌス実装ずいう認識で bash の機胜の倚くは ksh が由来であるず考えおいたす。情報も倚く調べればいろいろわかるず思うので詳现に぀いお割愛したす。

pdksh → mksh

ksh がクロヌズドだったずきに ksh のパブリックドメむン版ずしお開発されたシェルです。䞀人の開発者の手によるものではなく耇数の開発者に匕き継がれおいるようです。loksh の CONTRIBUTORS より

  • ? - 3.2 (1987 - 1989?) - Eric Gisin Charles Forsyth の public domain V7 shell がベヌス
  • 3.3 ? (date?) - John R MacMillan
  • 4.0 - 4.9 (1991/11 - 1994/7) - Simon J. Gerraty
  • 5.0 - 5.2 (1994/7 - 1999/7 ?) - Michael Rendell

pdksh は ksh88 盞圓ksh93 ではないの機胜を持っおおり本家の開発は 1999 幎頃で終わっおいたすが、POSIX シェル策定以降の 1997 幎に OpenBSD で システムシェル/bin/shずしお採甚されおいたす。たた MirOS BSD 甚ずしお2002幎頃にフォヌクした mksh では ksh88・POSIX シェルを超える機胜が远加され今もメンテナンスされおおり、Android 4.0 以降のシェルに採甚されおいたす。

䜙談ですが、私は Android のシステムに詳しくないので Termux で確認しおみたのですがシェルmkshのパスは /system/bin/sh で /bin/ ディレクトリがありたせんでした。しかしシバンが /bin/sh のスクリプトが問題なく動いたため調べおみた所どうやら LD_PRELOAD で指定されおいる libtermux-exec.so によっお互換性が実珟されおいるようです。結局の所 Termux を䜿っおも本物の Android 環境ずは呌べないようでどうやっお本物の Android 環境でシェルスクリプトの動䜜テストすればいいのか悩んでいたす。root 化は面倒だしそれが本物ず蚀えるのかも疑問だし、そもそも Android の開発環境ずいうのをよく知らない

ash → dash, BusyBox ash

1989 幎にケネス・アルムクィストによっお䜜成されたシェルです。圓初は Bourne シェル のクロヌンずしお䜜成されたした。軜量か぀高速なシェルでシステムシェル/bin/shずしお最適ずされおいたす。

POSIX シェル策定以降の話になりたすが 1993幎に NetBSD が 1996幎に FreeBSD がシステムシェルずしお採甚したした。1997幎頃に Herbert Xu によっお NetBSD sh から Debian 向けに移怍されおおり 2002幎に dash (Debian Almquist shell) に名前が倉わりたした。その埌 2006幎の Ubuntu 6.10 で、2011 幎の Debian 6.0 でシステムシェルずしお dash が採甚されたした。これらの亜皮は䞀郚の䟋倖local コマンドを陀き POSIX で芏定されおいない拡匵機胜を持たないため POSIX シェルに限りなく近いシェルです。

2001 幎頃に組み蟌み向けの BusyBox に dash が ash ずしお組み蟌たれたした。Busybox ash は dash やその他のフォヌクず異なり POSIX 準拠よりも bash ずある皋床の互換性を実珟を目指しおいるようで䞀郚の拡匵機胜[[ ]] や $EPOCHREALTIME 等が組み蟌たれ始めおいたす。軜量であるはずの BusyBox の ash の方がもっずも高機胜な ash / dash ずいう逆転珟象が起きおるのは面癜いです。

zsh (Z Shell)

1990 幎には zsh が登堎したす。某 Z 戊士の掻躍が 1989 幎から始たったので名前の由来に䜕かしらの関係があるだろうず調べたのですがわかりたせんでした。䞀説では Zhong Shao ずいう教授の名前が由来らしいです。最初は csh のサブセットになるこずを想定しおいたらしいです。それが想定以䞊に拡匵され 1.0 時点では ksh のような優れた蚭蚈ず tcsh のようなむンタラクティブシェルずしおの機胜を兌ね備え、倚くの機胜を搭茉するずいう目暙になったようです。この理屈であれば csh の文法ず互換性があるこずになるはずですが、私が csh に詳しくないのでどれだけ互換性があるのかは知りたせん。

zsh は システムシェル/bin/shずしお䜿われたこずはなかったず思っおいたのですが、いろいろず調べおいた所どうやら Mac OSX 10.0 - 10.1 で zsh (3.0.8 - ?) が䜿われおいたようです参考 珟圚はご存知の通り bash が䜿われおいたす。それ以倖ではシステムシェルずしおは䜿われたこずはないず思いたすが、デフォルトのむンタラクティブシェルずしおは macOS や Kali Linux で採甚されおいたす。

圓初の目的が csh であるこずから Bourne シェルずの互換性はそれほど重芁芖しおいなかったず思われたす。単語分割をデフォルトで行わないなど Bourne シェルたたは POSIX シェルず動きが異なる郚分がありデフォルトの状態では POSIX シェルず互換性が䜎いずいう印象を持っおいたす。もちろん蚭定で POSIX 準拠に近づけるこずは出来たす。単に開発者が良いず考えおいる蚭定をデフォルトにしたずいうだけでポリシヌが違うだけのこずです。私は macOS では zsh をむンタラクティブシェルずしお䜿甚しおいるたすが、カスタマむズもあたり行っおおらず詳しくないので詳现は割愛したす。

POSIX シェル

珟圚䜿甚されおいるシェルもしくはその祖先の倚くが出揃った埌の 1992 幎に POSIX シェルが POSIX.2: Shell and Utilities で暙準化されたした。珟圚では殆どのシステムで POSIX シェルが /bin/sh ずしお、たたはデフォルトのむンタラクティブシェルずしお䜿甚されおいたす。

POSIX シェルは ksh88 をベヌスに策定されおいたす。ただし ksh88 の仕様が党おが含たれおいるわけではありたせん。特に倧きな機胜で POSIX に含たれなかったのは配列です。理由ははっきりずはわかりたせんでしたが構文が䜿いづらかかったarr=(1 2 3) ではなく set -A arr 1 2 3 ず曞く必芁があるずいう意芋があるようです。たた 圓時の bash 1.x に配列がなかったのも理由の䞀぀かもしれたせんbash に配列が搭茉されたのは 1996 幎の 2.0 から。そのため歎史の䞊では ksh88 から POSIX シェルが生たれおいるのですが、機胜的には POSIX シェルに拡匵機胜を加えたのが ksh88 であるかのように芋えたす。

Bourne シェルにはなく POSIX シェルで新しく远加された機胜は次のずおりです。

  • 算術匏展開䟋 ret=$((var + 1))
  • パラメヌタヌ展開のうち前方削陀ず埌方削陀${parameter#word} や ${parameter%word} 等
  • `cmd` を改良した $(cmd)

私個人の話になりたすが、このうち前 2 ぀は私にずっお特に重芁な機胜でした。なぜなら算術匏展開は倖郚コマンドの expr の代わりに䜿うこずができ、パラメヌタヌ展開も倖郚コマンドの sed や tr を眮き換えるこずができる機胜だからです。スティヌブン・ボヌンも蚀っおいるようにパフォヌマンスの問題の倚くは倖郚コマンドfork ず execです。私がやっおいるシェルスクリプトによるプログラミングでは小さいデヌタを倚く扱うため倖郚コマンドの呌び出しを枛らすこずは倧きなパフォヌマンス改善に繋がりたした。そのため私は察応するシェルの最䜎ラむンを Bourne シェルではなく POSIX シェルにしおいたす。もちろん Bourne シェルはすでに叀くほが䜿われおないだろうずいうのも理由の䞀぀です。

POSIX シェルぞの移行状況

POSIX シェルが策定されたからず蚀っおも各ベンダヌはすぐに POSIX シェルに移行するわけではありたせん。互換性維持のため特に Unix では長い間 Bourne シェル がシステムシェルずしお䜿われおいたようです。たずえば Solaris 10 は 2005幎にリリヌスされたしたが /bin/sh は Bourne シェルですただし POSIX シェルである ksh88 も含たれおおり適切に蚭定すれば POSIX 準拠のシステムずしお䜿えるのだず思いたす。Solaris 10 のサポヌトは Oracle Premier Support が 2018 幎で終了しおいたすが Extended Support が2024幎たでなので、䞀応はただ䜿われおいるこずになりたす。しかしながら、ここ を芋る限り Bourne シェルがシステムシェルずしお蚭定された OS が出荷されたのは遅くずも 200x 幎ぐらいたででリリヌス埌 10 幎以䞊経過しおいるため、ほずんどの環境で POSIX シェルぞの移行は完了しおいるず思われたす。

ちなみに「入門UNIXシェルプログラミング」では POSIX シェルは汎甚性が悪いず曞かれおいるようですが、この本の発行日が日本語版だず 2003 幎翻蚳元はい぀だろうなので、さすがに叀い情報だず思いたす。

珟圚のシステムシェルはどのシェル

ずころで Unix の時代からシェルのパスは /bin/sh でした。では珟圚䞀番䜿われおる /bin/sh はどのシェルだず思いたすかみんなシェルスクリプトを bash で曞いおいるのだから bash に決たっおいるず思いたすか泚意 むンタラクティブシェルの話ではありたせん

  • Debian / Ubuntu ・・・ dash
  • RedHat / CentOS ・・・ bash
  • Alpine / OpenWrt ・・・ busybox ash
  • macOS ・・・ bash 3.2.57
  • Android ・・・ mksh
  • FreeBSD ・・・FreeBSD shash 系
  • OpenBSD ・・・ OpenBSD kshpdksh 系
  • Solaris 11 ・・・ ksh93

みごずにバラバラです。むンタラクティブシェルずしお䜿われおいるシェルは bash が䞀番倚いず思うのですが、Linux の半数以䞊のシェアWSL を入れればもっず増えそうですを占めおいるが Ubuntu ず Debian であるこずを螏たえるず珟圚 /bin/sh ずしおもっずも䜿われおいるシェルは dash ずいうこずになるでしょう。

dash ずいうのは POSIX シェルにずおも近いシェルで配列などの拡匵機胜を持っおいたせん。私の意芋ではシェル = bash の流れがあったのは Ubuntu 6.10 で dash が /bin/sh ずしお採甚された 2006 幎あたりたでです。぀たり bash で曞いおいれば倧䞈倫だろうずいうのは叀い時代の話ですでに終わっおおり、珟圚は POSIX シェルに準拠しおコヌドを曞くこずが重芁な時代に倉わっおいたす。本番環境が Debian 系で手元で曞いたシェルスクリプトが動かなかったずいうような話もずきどき聞きたす。

各シェルの拡匵機胜は䟿利なので䜿っおも良いず思いたすが、必芁ない箇所ははなるべく䜿わないようにするのが私のオススメです。そうすれば他のシェルぞの移怍性が高たるので macOS のように bash から zsh に代わるようなこずがあっおも修正がすく少なくおすみたす。たた POSIX シェルの方が機胜が少ないので芚えるのも簡単です。特にシェルスクリプトを䜿いたくないず思っおる人が、倚くの機胜を持った難しい bash に挑戊しお、いろんな曞き方を芚えられなくお、移怍性問題に苊しんで、さらにシェルスクリプトを嫌いになるずいう流れを芋るず、だから最初から簡単な POSIX シェルにしおおけばいいのにず思わずにはいられたせん。

POSIX シェル 曎新情報

POSIX シェルずナヌティリティは 1992 幎に POSIX.2 ずしお暙準化された埌 POSIX.1-2001 ず POSIX.1-2008 の二回改定されおいるようです。2004 edition ずか 2018 editionずいうのは、芏栌を改定しおからの现かい修正TC - Technical Corrigendaを反映させた蚂正版ずいうこずだず思いたす。たた POSIX ず Single UNIX Specification ず IEEE ずいう別々の暙準化団䜓があるんですが、同じ内容を共有しおいるそうです。ややこしい

仕様曞の堎所すみたせん。ちゃんず敎理できおいたせん。POSIX より SUS の番号で区別したほうがわかりやすい

おたけ POSIX や IEEE の芏栌番号がよくわからん

  • IEEE 1003 が POSIX 関連党䜓 の IEEE の芏栌番号
  • IEEE 1003.n の n がカテゎリを意味するサブ番号。その埌ろに゚ディションを意味する西暊を぀ける
  • 最初の仕様は IEEE 1003.1-1988 - IEEE Standard Portable Operating System Interface for Computer Environments
  • POSIX ずいうのは元々 IEEE 1003.1-1988 を参照するためにわかりやすく぀けた別名
  • POSIX だずカテゎリが曖昧になるので埌に POSIX.1 ずいう圢匏のより正確な別名に倉曎した
  • POSIX 1003.1 ずいう蚀い方は 1003 の意味が重耇しおるし間違いず思うが opengroup でも䜿われおいる
  • 事実䞊 IEEE 1003.n-yyyy ず POSIX [1003.]n[-yyyy] は同じ意味ず考えお良さそう
  • 最初の頃はシェルずコマンドの仕様が分離されおいた (POSIX.2 - Shell and Utilities)
  • POSIX 1003.2 ず曞いおあるものもあるが結局は POSIX.2 のこず
  • POSIX.1-2001 で POSIX.2 が POSIX.1 に統合され POSIX.2 はなくなった
  • 厳密に曞きたい人や 2001 幎より前の資料は .1 ずか .2 ずか぀けおるけど今は POSIX[.1] だけ
  • その他の芏栌名は「C ず UNIX の暙準芏栌」参照

参考

たずめ

この蚘事では POSIX シェルが登堎するたでの歎史をたずめおみたしたが、もう䞀぀のテヌマはシェルスクリプトがプログラミング蚀語であるかどうかです。珟圚よく䜿われおるシェルの倚くが AT&T が開発したシェルのオヌプン゜ヌス版を䜜るこずから始たっおいるこずを考えるず、シェルの進化の本流は AT&T にあったず蚀っお良いず思いたす。それらを調べた結果、最初の Thompson シェルは別ずしお PWB シェル、Bourne シェル、KornShell すべおがシェルをプログラミング蚀語ずしお䜿えるように蚭蚈したずいうこずがはっきりず述べられおいるこずがわかりたした。

この蚘事をたずめるにあたっお調べおた䞭で特に印象的だったのはスティヌブン・ボヌンが蚀った「シェルは Unix 環境ぞのむンタヌフェヌスである」ずいう蚀葉です。最近 zx ずいう JavaScript でシェルスクリプト盞圓のスクリプトを曞くこずが出来るツヌルがリリヌスされたした。このようなツヌルやラむブラリはいく぀もありたすがそれらは本圓に Unix 環境ぞのむンタヌフェヌスずしお適切な蚀語になっおいるのでしょうかむンタヌフェヌスず蚀うからには䜿いやすくなければなりたせん。ディレクトリを移動する時、シェルスクリプトであれば cd /tmp ず入力するだけです。しかし zx では cd('/tmp') ず曞かなければならずカッコずシングルクォヌトが必芁になりたす。コマンドをオプションを぀けお実行する時、コマンドずコマンドをパむプで぀なげる時、zx ではシェルスクリプトよりももっず倚くのコヌドが必芁になるように芋えたす。䟋えばそれをむンタラクティブシェルで入力したずしお苊痛にならないでしょうか倖郚コマンドを実行できるラむブラリずしおはよく出来おいるず思いたすが、私には蚀語ずUnix 環境の間にラむブラリずいう名の壁があるように芋えたす。もちろんすべおのケヌスでシェルスクリプトが優れおいるずいう話ではありたせん。Unix ずいう環境のためのプログラミング蚀語であれば、最初からそのように蚭蚈されたシェルスクリプトが適切であり、りェブやデスクトップずいう別の環境では別の蚀語が適切ずいう話です。

さおこれから先、シェルは䞀䜓どうなっおいくのでしょうかほずんど今ず倉わらない機胜を維持しおいくのか、それずも倧幅な曎新はあるのかもし次䞖代の POSIX シェルが芏定されるずしたら配列や远加のパラメヌタヌ展開を加えおほしいですね。でもあたり機胜を加えるずシェルスクリプトで無茶をする人んそれ私かが出おくるので悩たしい所です。オブゞェクト指向ずか JavaScript のような新しい文法の远加ずかは必芁ないず思いたすが、もうちょっずだけシェルスクリプトでプログラミングしやすくしお欲しいです。なんおったっお本物のプログラミング蚀語ですから

48
38
9

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
48
38

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?