10周年のSPコンテンツ!

POSIXにおけるShebangの解釈についてのシェルショッカーとの議論まとめ

シェルスクリプトでは1行目にShebang(シバン)を書くことがある。 #!/bin/sh これがPOSIXに定義されているかどうかシェルショッカーが議論していた。参考になったのでまとめた。 また同じタイミングでPOSIXで定義されているCコンパイラーに関する話題もあったので一緒にまとめた。 続きを読む
プログラミング posixism POSIX shellscript posix原理主義 シェルスクリプト
12
POSIXでのShebangの解釈
シェルショッカーとの議論
Kazuho Oku @kazuho
POSIXでshell scriptって、そもそも#! の動作がきていされてなかった気が / “恐怖!シェルショッカーの POSIX原理主義シェルスクリプト” htn.to/BWG2wx
ShellShoccar-jpn, a secret society @shellshoccarjpn
.@kazuho それは聞き捨てならんな。まず#!がファイル先頭に出てきた時の動作はexecveのman pubs.opengroup.org/onlinepubs/969… に、その後shに制御が渡されてからの動作はシェル文法の頁 pubs.opengroup.org/onlinepubs/969… に記述があるが。
Kazuho Oku @kazuho
.@shellshoccarjpn #!が先頭にある場合execveがshを呼ぶことは保証されるが、そのファイルを受け取ったshが#!をどう解釈するかは pubs.opengroup.org/onlinepubs/969… にあるとおり unspecified なのでは? つまりサーバが爆発するかも
Kazuho Oku @kazuho
あー正確にいうと、#! がついてようがついてなかろうが実行可能形式じゃないファイルを execve した場合 sh に渡すことが POSIX 的には OK で、それを sh がどう解釈すべきかは規定されていない
Kazuho Oku @kazuho
つまりPOSIXは「ファイルが実行形式じゃなければsh scriptに決まってるだろ」というような処理系を許容していて、そういう処理系においてはsh以外を用いてスクリプトを書くことがないから #! に関する仕様は POSIX に含まれていない
Kazuho Oku @kazuho
#! について、例えば「○○のように処理すべき、あるいはコメントとして無視しろ」という規定があれば #! /bin/sh は POSIX においてポータブルだと言えるんだろうと思うんだけど
SODA Noriyuki @n_soda
@kazuho これ、execlp()とexecvp()に限定されてるので、execve() とかじゃシェル呼び出せなくてもいいっぽいですね。UNIX v7 の頃からそうなってて、へーって感じ(昔どこかで見た気もするけど忘れてました)tuhs.org/cgi-bin/utree.…
Kazuho Oku @kazuho
@n_soda あーすみませんそこは適当に書きました。おっしゃるとおりかと思います
ShellShoccar-jpn, a secret society @shellshoccarjpn
.@kazuho 確かにそこのunspecifiedという単語には引っかかったのだ。だが「#!で呼び出したインタープリターの動作に依存するので結果はunspecifiedだ」と言いたいのだろうと我らは汲み取ったぞ。#!があった時のみ爆破してもよいなどと言いたかろうとは思えんからな
Kazuho Oku @kazuho
.@shellshoccarjpn #!がある場合に、その値に基づいてインタプリタを呼び出さなければならないなんて規定はありませんよ
ShellShoccar-jpn, a secret society @shellshoccarjpn
.@kazuho ほほう、なかなか興味深いことを言うな。ならば@kazuhoよ、そのようにPOSIXの文章が曖昧に書かれていることについて、それはPOSIX文書の欠陥だと思うか?それとも意図的に爆発でも何でも自由にさせられる余地を残したと思うか?
AoiMoe a.k.aしお兄P @AoiMoe
POSIX的には実行ファイル形式を規定してない以上、shebangみたいなマジックナンバーを記述できる余地がない
Kazuho Oku @kazuho
POSIX.1-2008 では execve で指定されたファイルが実行形式でない場合、sh に渡すか、あるいは #! の値を見てインタプリタを直接起動することが求められていると思う
ShellShoccar-jpn, a secret society @shellshoccarjpn
.@kazuho なるほどな。確かに、a.outやらELFやらをPOSIX文書で探してみたが見つけられなかった。POSIXは実在の実装ありきで後から整備された規格ゆえ、実行ファイル形式への言及が抜けてしまったのかもしれんな。だがそれなら改訂を機に追記してもらいたいものだがな。
ShellShoccar-jpn, a secret society @shellshoccarjpn
.@kazuho 我ら同様に侵略を目論むどこかの部隊の曹長のようだな。関係ないが、POSIXの興味深い話を聞かせてもらった礼に、一ついいことを教えてやる!このうがい薬はうまいらしいぞ。family.saraya.com/products/colol…
POSIXでのファイル実行時の動作
AoiMoe a.k.aしお兄P @AoiMoe
shebangがないシェルスクリプトをexecveに渡すとエラー返すので必要に応じて自分で/bin/shを蹴るというのが今のUNIX系OSの作法だが、こんなのもPOSIXには規定できる余地がない
Kazuho Oku @kazuho
@AoiMoe いや、それは "now required by POSIX.1-2008" かと。see pubs.opengroup.org/onlinepubs/969… の rationale
AoiMoe a.k.aしお兄P @AoiMoe
@kazuho 規格の本体じゃなくてそっちに書いておくという手があったか
Kazuho Oku @kazuho
@AoiMoe いや本体にもあります。execのIn the cases where the other members of the exec family of functions would fail から始まる文
AoiMoe a.k.aしお兄P @AoiMoe
@kazuho ああそうか、PATH見る系の奴はそういう風に規定されてないと現実の実装との齟齬が出るので、わざわざそう書いてあるんですね。
AoiMoe a.k.aしお兄P @AoiMoe
まあでも、やっぱり規格の本体ではこういう書き方になるよな、という書き方ではある。
残りを読む(83)

コメント

. @senopen 2016年3月24日
まとめを更新しました。
. @senopen 2016年3月28日
どなたかわかりませんが、最後の「スクリプトのインタープリターを指定する方法の歴史」と「スクリプト先頭が「#」だったら問答無用でcsh呼び出す仕様について」の見出しづけありがとうございます。
ログインして広告を非表示にする
ログインして広告を非表示にする