#macOS の #Apache で #CGI のshebangに融通が効かなくなった時の対処法


概要

plenvを使っているのでPerl/CGIのshebangを#!/usr/bin/env perlとして、動的に対応できるようにしていたのが、特にMacの設定を変えていないのにもかかわらず、急に500 Internal Server Errorを吐くようになった。

追記部分にもある通り、何かしらの理由(おそらく私が操作した)で起動するApacheを間違えていたことに起因するようだ。

事象について

500errorの原因はPerlのモジュールが不足しているという内容であったが、確実にインストール済みのものであった。ちょっと調べると、実行しているバージョンが違うためにモジュールのインストールが正しく判定されていないのだと判明。
従来は#!/usr/bin/env perlと書いておけばこれがplenvで変更したバージョンのperlを自動的に返すので問題がなかったが、私の知る限り2020年9月15日(火)からこれがApache内でusr/bin/perl(system)を返すようになったようである。(ググるとこれ前からだったみたいなんですけど、私の環境だけ特別だったのかな?)

環境

  • macOS Catalina 10.15.6 (19G2021)
  • Apache/2.4.46 (Unix) (Homebrewでインストール)
  • /usr/bin/perl -v(system) はv5.18.4
  • plenv global で5.26.3を使用していた。

🆕妥当な解決策(2020/09/19追記)

よく調べたところ、実行しているApacheのバージョンがhomebrewでインストールしたものより古かった。デフォルトでOSにインストールされているhttpdの方が走っていたようだ。
こちらを参考に、デフォルトのApacheを止め、新しいApacheを有効にすると#!/usr/bin/env perlplenv globalで指定したPerlのバージョンを反映するようになった。

$ sudo launchctl stop /System/Library/LaunchDaemons/org.apache.httpd.plist
$ sudo launchctl unload -w /System/Library/LaunchDaemons/org.apache.httpd.plist
$ sudo apachectl stop # デフォルトの方を止める
$ brew services start httpd # homebrew版を起動
$ apachectl restart
test.pl
#!/usr/bin/env perl

use CGI::Carp qw(fatalsToBrowser);

die "the version of perl is $^V\n";
#the version of perl is v5.26.3

ダサい解決策

$ cd /usr/local/bin
$ where perl # 既に /usr/local/bin/perl がないことを確認
$ ln -s /Users/[your_name]/.plenv/build/[\d+]/perl-5.xx.x/perl # ←同名のファイルを作る場合は第2引数は省略できる

として、利用するCGIのshebangを#!/usr/local/bin/perlに書き換えればいい。動的にplenvできなくなるので納得は行かないが当面はこれで我慢しようと思う。最初からこれは通るだろうと思ってはいたがあまりにも無粋な策なので後回しにしていた。

他に試した方法

zshなら$ where perlでパスの通ったperlの絶対パスを確認できるが、
/Users/[your_name]/.plenv/shims/perl

直接shebangに指定する

これもスマートな方法ではないが、当初はこれで行けるだろうと思っていたもの。
こちらのおかげで上記の解にたどり着いた。

このsymlinkを/usr/local/bin/perlにしてみる

まぁ、リモートの環境とshebangを揃えるならこうなるだろう。上記と同じ理由でうまくいかない。

Perlモジュールを入れ直す

文法的に新し過ぎて古いインタプリタが解釈できない書き方をしていないのであれば、結局のところモジュールが足りないというエラーに終始するので入れ直せば良い。DBD::mysqlのインストールで躓かなければ、plenv migrate-modules 5.26.3 systemで全然いけたはず。

Apacheの設定の見直し

httpd.confをざっと読んだが、そもそも直すところがなかった。
🆕設定に変わりなくても再起動を試せば良かったということ

Macの再起動

わりかし初期に、淡い期待を抱いて実行したが全く効果なし。

試していないもの

plistの編集

STACK OVERFLOWの10年前の質問と回答って参考にならないでしょ?と思った。

この問題の根っこ

/usr/bin/env *の返す値がシェルとApacheで違うところなのでこれはPerlの問題ではありません。(かと言って今時Perl以外でCGIを新規構築する猛者がいるとは思わないけど)