(前振りはこちら)
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