perlスクリプトの実行とシバン行

| | トラックバック(0)

カテゴリ:

(前振りはこちら)
gitを入れようとしてMacPortsを入れてwgetを入れようとして挫折

(承前)

Perlが2つインストールされてしまった。

一つは /usr/bin/perl (MacBook Proにもとから入っている)

もう一つは /opt/local/bin/perl (MacPortsがインストールした)

こうなると、いままで動いていたスクリプトが動かなくなる。かもしれない。
いやでも、Perlスクリプトの一行目にはおまじないでいつも

 #! /usr/bin/perl  

と書いている。

これってまさにPerlのパスそのものなので、
Perlスクリプトの1行目でこれを買いている限り、
Perlが複数インストールされてしまっていてもきちんと動くんじゃないの?
と淡い期待をもった。

それで、

perl 〇〇.pl

と打った。いままでだったら動いていたスクリプトが動かない!オウノウ!
やっぱりかー、やっぱりですかー。
動かない理由は・・・、あ、useしてるモジュールが見つからないと。
ということは、コアモジュール以外のモジュールを使ってないスクリプトなら
動くの?→動いた。

んー、あ、PATH?perlって打った時に「/opt/local/bin/perl」のperlじゃなくて
「/usr/bin/perl」のperlを呼ぶように明示的に指定してやればいいのか?と思い、
下記のように実行

/usr/bin/perl 〇〇.pl

ちゃんと動きました。ああこうすれば動くんかーと、納得。

「 perl 」と打った時に、コンピューターはそのプログラムがどこに
あるのかを予め設定された場所を検索して探すのだけど
(検索場所を予め設定することを「PATHを通す」、と表現する)、
そうやって探させた結果、「 /opt/local/bin/ 」で先に見つかってしまっている
ということなのだと思う。
(だから今回の解決法は、/opt/local/bin/のPATHを削除するか
 優先順位を変えればよいのか?)

そのようなわけで、perlを検索させないで、直接実行するPerlを
指定してやれば動くのだ、ということでめでたしめでたし?

あれでもこうやって、起動するPerlを指定できない場合ってどうすんの?
例えば、Webサーバーで動いているCGIスクリプトは?

と思って、自分のMacの中でApacheで動いているCGIスクリプトが
動くかチェックしてみた。

・・・・。

動いてる!

え、なんで?と思ったわけなのですが、そのあたりからPerlを実行するというのは
どういうことなんだろうということを考えだしました。

そもそも Perlスクリプトの一行目にはおまじない 「 #! /usr/bin/perl 」
これはなんなんだ?、と。

perl 〇〇.pl

とやって動かなかったので、その一行目は単なる飾りか
さもなくば動作するPerlを指定する以外の用途のためにあるのかと
思ったりもしてしまいましたが、
Apacheが動かすCGIスクリプトがちゃんと動作したことから、
その一行の情報を利用して動いたのだと考えないと、
つじつまがあわない。

そういえば、Perlプログラムを実行するとき、

perl 〇〇.pl

とやらないで、

〇〇.pl

と、単にファイル名だけで実行する方法があったような。

・・・・・。(やってみた)

動かなかった。
あれー、シェルスクリプトはこれで動くんだけどなあ。
パーミッションがおかしいとあか?いや、 755 になってる。

あ、ファイルの指定の仕方が悪いのか?
"このディレクトリにある"という意味で「 ./ 」をファイル名の前につけてみる。

./〇〇.pl

実行できた!
動いているってことは、もともとの「 /usr/bin/perl 」の方が実行された
ということだ!

ということで、プログラムを実行するということや、
スクリプトの1行めの意味がわかってくる。

perlと指定しないで、プログラムのパスのみで実行させる場合は、
スクリプトの一行目の情報が重要になってくるのだ!

で、このスクリプトの一行目は「シバン行 (shebang)」と言うらしい。
日本語だと、「シェバング行」とか「シェバン行」とかいう言い方も
されるよう。( bang の最後の g は英語だと普通発音しない)

シバン (Unix) - Wikipedia
Shebang (Unix) ^ Wikipedia(en)

Wikipediaにあるようにように、
スクリプトを実行するインタプリタを指定する役目をしている。

だから特にPerlに限った話ではなく、
それがシェルスクリプトならば

#! /bin/sh

という一行を先頭に書くとシェルが動きます。例え拡張性が.plであっても(多分)

というわけで、

./〇〇.pl

とスクリプトを実行した場合、
一行目のシバン行によって、シェルがどのPerlで実行するかを判断してくれるため、
複数Perlが入っていてもスクリプト一行目に記述したPerlで
実行されます。

一方、

perl 〇〇.pl

とやった場合は、PATHを検索して見つけたPerlでスクリプトは実行されて、
シバン行はなかったことにされる、ということのようです。
(実際、#で始まる行はコメントとしてPerlは無視するし。)

なんというか、「そんなことも知らなかったの?!」と驚かれるような
内容で、UNIXのイロハを知っていれば上記のような理解は知っていて
当たり前なのだろうと思いますが、
独学でLinuxやらPerlやらを学んできたので、そういう初歩的なことが
わかっていなくて、逆にわかってみると「目からウロコ!」的に、
いままでのもやもやがスッキリしました。

はい、お目汚し失礼しました。

参考にさせていただいた記事:
http://okwave.jp/qa/q4757232_2.html

トラックバック(0)

このブログ記事を参照しているブログ一覧: perlスクリプトの実行とシバン行

このブログ記事に対するトラックバックURL: https://nozawashinichi.sakura.ne.jp/MT-4.25/mt-tb.cgi/1077

comments powered by Disqus

このブログ記事について

このページは、Shinichi Nozawaが2013年4月12日 16:15に書いたブログ記事です。

ひとつ前のブログ記事は「gitを入れようとしてMacPortsを入れてwgetを入れようとして挫折」です。

次のブログ記事は「DBIとDBI::SQLite モジュール」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。