シェルスクリプトの実行の BSD と Linux の違い(?)について質問です。


実務上で困ったことがあるわけではなく、すごく興味本位なものですが、
手元の OpenBSD システムでは、パーミッションが 100(--x------) でオーナーは自分であるシェルスクリプト、例えば内容は簡単に

#!/bin/sh
echo test

といったものを(編集は root 権限で行ったとして)、

$ ./XXX
test

として実行することができます。

しかし翻って手元の Ubuntu (Linux) で同じ条件で実行しようとすると

$ ./XXX
/bin/sh: Can't open ./test

と、 shebang 中のインタプリタがファイルをオープンできない旨が表示されました。

この違いについて調べたいのですが、どこから検索したものかわからず、質問してみました。そもそもこれが BSD と Linux というレベルの違いによるものかもわかっていなかったりします。
どうぞよろしくおねがいします。

回答の条件
  • 1人2回まで
  • 13歳以上
  • 登録:2010/05/02 07:31:19
  • 終了:2010/05/02 18:20:38

ベストアンサー

id:b-wind No.5

b-wind回答回数3344ベストアンサー獲得回数4402010/05/02 17:03:47

ポイント70pt

shebang 自体の解釈をどのように行っているかを理解すればいいかな。

#!/bin/sh

ファイルの先頭に shebang がある場合、勝手にそのプログラムが呼ばれるわけではない。

該当のスクリプトの場合以下のように読み替えてから再度実行する形になる。

/bin/sh ./XXX

shebang の記述にファイル名自体を引数として与えると言うことだ。


この為同じコマンドをログインシェルから直接実行したのとほぼ等価。

実行するために実行権限が、引数に与えられたファイルを読み込むために読込権限が必要。

手元の環境で試す限りでは FreeBSD / CentOS の双方において、

  • root としてログインした環境 実行可能
  • 一般ユーザーとしてログインした環境 実行不可

となった。

読み書き、実行とも同じユーザーで実行した結果だ。


Ubuntu での実行の仕方自体に違いがあるのでは?

sudo /bin/bash

とかやってから実行すると結果が変わるかもしれない。

id:oogatta

実際に動作確認までしていただいて、ありがとうございます!

・shebang がどう処理されているかを理解することから取りかかる

・"この為同じコマンドをログインシェルから直接実行したのとほぼ等価。"

とてもためになりました。実際に shebang でいくつか検索してみたところ、さらに自分の理解も深まりました。

仮想環境に FreeBSD や NetBSD も入れて、自分の手でももう少し試してみます。本当にありがとうございます。

(追記)

FreeBSD および CentOS でも試してみました。

(インタプリタが実行する)スクリプトファイルのパーミッションを 100 とした場合の所有者による実行は、Ubuntu 同様不可能でした。

再度試しましたが、 OpenBSD ではこれが可能です。ご教示いただいた流れで shebang について色々検索しまして、

http://www.in-ulm.de/~mascheck/various/shebang/

こちらに、 OpenBSD/NetBSD 系ではファイルディスクリプタをカーネルが開いた状態でインタプリタに渡してあげる仕様があるようで、

そのためではないかと考えています。

示唆いただいて本当に助かりました。自分としてはこれで腑に落ちましたので質問を終了させてください。

みなさまどうもありがとうございました。

2010/05/02 18:19:48

その他の回答(4件)

id:koriki-kozou No.1

koriki-kozou回答回数480ベストアンサー獲得回数792010/05/02 09:20:09

ポイント30pt

読み込み権限が無ければ実行権限があっても実行できない

・OpenBSD root権限は完全に開放されていてパーミッションを無視して読み取り可能

・Ubuntu rootでのログインが規制されておりsudoによる実行しかできないためパーミッションを無視できない

id:oogatta

あ…、なるほど!

OpenBSD の場合、 root として実行しなくても実行時に何らかの root への権限委譲が発生して、

実際には root として普通に読み取りに行っているだけだ、というわけですね!?

ありがとうございます。もう少し色々試して考えてみます。

2010/05/02 11:40:45
id:tama213 No.2

tama213回答回数486ベストアンサー獲得回数302010/05/02 10:52:55

ポイント20pt

Linuxの/bin/shの正体がbashだから

id:oogatta

ありがとうございます。やられました。そうでした。

シェルレベルの話なのかカーネルレベルの話なのかまだ釈然としていないのですが、

ヒントをありがとうございます。そうでした…。

(追記)しかも Ubuntu の場合は "dash" ですもんね…。全く失念しておりました。ありがとうございました。

2010/05/02 11:43:52
id:kick_m No.3

kick_m回答回数1372ベストアンサー獲得回数542010/05/02 11:39:54

ポイント10pt

echo "test"

と引用符をつけないと。

id:oogatta

え!?

と一瞬思いましたが、さすがに一単語ですし、クォート無しでも大丈夫でした。

有り無しで挙動も変わらないようです。ほっ…。

2010/05/02 11:57:14
id:kick_m No.4

kick_m回答回数1372ベストアンサー獲得回数542010/05/02 14:24:14

ポイント10pt

だから実行できないわけでしょ。

id:oogatta

読み込み権限を与えてあげれば、実行はできるんです…。

2010/05/02 17:17:37
id:b-wind No.5

b-wind回答回数3344ベストアンサー獲得回数4402010/05/02 17:03:47ここでベストアンサー

ポイント70pt

shebang 自体の解釈をどのように行っているかを理解すればいいかな。

#!/bin/sh

ファイルの先頭に shebang がある場合、勝手にそのプログラムが呼ばれるわけではない。

該当のスクリプトの場合以下のように読み替えてから再度実行する形になる。

/bin/sh ./XXX

shebang の記述にファイル名自体を引数として与えると言うことだ。


この為同じコマンドをログインシェルから直接実行したのとほぼ等価。

実行するために実行権限が、引数に与えられたファイルを読み込むために読込権限が必要。

手元の環境で試す限りでは FreeBSD / CentOS の双方において、

  • root としてログインした環境 実行可能
  • 一般ユーザーとしてログインした環境 実行不可

となった。

読み書き、実行とも同じユーザーで実行した結果だ。


Ubuntu での実行の仕方自体に違いがあるのでは?

sudo /bin/bash

とかやってから実行すると結果が変わるかもしれない。

id:oogatta

実際に動作確認までしていただいて、ありがとうございます!

・shebang がどう処理されているかを理解することから取りかかる

・"この為同じコマンドをログインシェルから直接実行したのとほぼ等価。"

とてもためになりました。実際に shebang でいくつか検索してみたところ、さらに自分の理解も深まりました。

仮想環境に FreeBSD や NetBSD も入れて、自分の手でももう少し試してみます。本当にありがとうございます。

(追記)

FreeBSD および CentOS でも試してみました。

(インタプリタが実行する)スクリプトファイルのパーミッションを 100 とした場合の所有者による実行は、Ubuntu 同様不可能でした。

再度試しましたが、 OpenBSD ではこれが可能です。ご教示いただいた流れで shebang について色々検索しまして、

http://www.in-ulm.de/~mascheck/various/shebang/

こちらに、 OpenBSD/NetBSD 系ではファイルディスクリプタをカーネルが開いた状態でインタプリタに渡してあげる仕様があるようで、

そのためではないかと考えています。

示唆いただいて本当に助かりました。自分としてはこれで腑に落ちましたので質問を終了させてください。

みなさまどうもありがとうございました。

2010/05/02 18:19:48

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません