スレッドメモ

MLやNewsのスレッドをメモする試み。

2003|01|02|04|05|06|07|08|10|11|
2004|01|04|05|06|07|08|09|11|12|
2005|01|02|04|08|09|
2006|01|03|04|08|
2007|01|05|
2009|05|

2006-01-05 (木)

[linux-users] #!で始まるスクリプト

[106086] Shigeru Makino (1/5)

そこで、/bin/exeコマンドというものを作ってみることにしました。

http://www.line.to/mac/soft/exe/

#!/bin/exe gawk -f
#!/bin/exe perl

のようにサーチパスに入っていれば、 コマンドの絶対パスを書く必要がありません。

ほかに同様の問題をもっとスマートに、 解決する方法があるでしょうか? この方法に重大な問題点はあるでしょうか?

[106087] matu (1/5)

良くわかっていないのですがひょっとして、

#!/usr/bin/env perl

みたいなものを実行したいという話でしょうか。

[106088] Shigeru Makino (1/5)

そうです。 perlの場合はそれでうまく行きます。 awkの場合は、

#!/usr/bin/env awk -f

となりますが、 /usr/bin/envの第一引数が、"awk -f"と一纏めに送られるため、

/usr/bin/env: awk -f: そのようなファイルやディレクトリはありません

とエラーになります。

[106089] Koyama Mituru (1/5)

 ちょっと興味を持って調べてみました。

Linuxのようにshebankの複数の引数を、まとめてひとつとしてしまうもの。
古いFreeBSDのように引数をわけてくれるもの。
Solaris8のように最初の引数だけ渡してくれるもの。

があるんだそうです。

[106093] Takeshi Kusune (1/5)

> 簡単なプログラムなのに、exeの同類のプログラムによるアプローチがなかったことに、
> 自分の見落とした弱点があるのではないかと実は躊躇しています。

単純に、そこまで色々な環境での実行を想定している時点で、 PATH 変数に頼る危険性も避けるべきと考えてしまうのではないかと。

自作の script を自分のとこで動かす分には環境を自分であわせればいいし、 自分で好きにできない環境は個別に見ないと信用できない、ということかな? 自作 script 向けの環境差異吸収ツールとしてはありかもしれませんね。

[106094] Takashi SHIRAI (1/6)

 そもそも「#!」の展開は、昔は system call ではなくて shell のお仕事でした。

 なので、例えば Linux の標準 shell である bash でも、内部で 「#!」を処理するコードが実装されてますね。因みにこの実装では 最初の引数一個のみ評価します。

> 新しいFreeBSDは、一纏めに変更になっているのでしょうか?

 「新しい」と言っても極最近の話のようですね。昨年の頭から旧 来実装に関する議論が勃発して、年末に正式リリースとなった新版 で採用された新仕様なんで。

 コマンド名以降は行末まで全部が単一の引数になっていますが、 行末の空白文字は取除かれるみたいです。経緯の詳細は以下の URL から始まる thread を参照して下さい。

http://lists.freebsd.org/pipermail/freebsd-arch/2005-February/003525.html

> Solaris8の仕様は手の打ちようがありませんね。
> もっとも、
> #! /usr/local/bin/gawk -f
> とexeを使わずフルパスで書いても動かないのだから、
> もともとawk scriptを書けない仕様と言うことになりますね。

 最初の一個の引数は有効でしょう。二個目以降が無視されるだけ のことで。

 そもそもコマンドに渡される引数はそのコマンドを呼出した時の 引数がそのまま渡される筈で、script 先頭行に記述された引数が その直前に挿入されるというのは特例措置だと見なすべきです。

 ここに長々と引数を記述するような script は考え方が何か間違 っているんじゃないかと思いますよ。「#!」の後ろは「/bin/sh」 しか書かない、くらいの潔さがあってもいいかも。

 因みに「#!」の後ろの空白文字を無視出来ない実装もあるので、 移植性を考えるなら「#!」の直後にパス名を記述する癖をつけた方 がいいかも。大昔の実装だとそういう仕様が多いです。

[106106] SUZUKI Yasuhiro (1/7)

出沢さんが[linux-users:106095] で、'#! 〜'の処理は シェルからカーネルに移ったというような発言をされて いますが、

# しらいさんの[linux-users:106094] でもそういう
# 印象を受けます。

スクリプトファイルをコマンドラインなどで 実行する際に、まず初めに処理するのは、 相変わらずシェルではないでしょうか?

# execve()で、スクリプトファイルを直接実行
# 可能であるとは知りませんでしたが。

[106108] SUZUKI Yasuhiro (1/7)

MANページを'#!'で検索して読んでいたため 見落としましたが、

このファイルが実行可能フォーマットで
ないために実行が失敗し、かつディレクトリ
でもない場合には、このファイルはシェル
スクリプト(shell script)であると見なされます。

とbashのMANページにありました。

'#! 〜〜'が第1行目のファイルは、execve()システム コールで処理され実行が成功するようになって いますので、シェルにシェルスクリプトと認識される 段階には至らず、シェルが '#! 〜〜'を処理することは ないようですね。

お騒がせしました。


2003|01|02|04|05|06|07|08|10|11|
2004|01|04|05|06|07|08|09|11|12|
2005|01|02|04|08|09|
2006|01|03|04|08|
2007|01|05|
2009|05|