Perlを呼び出す移植可能な方法

Perlを呼び出す移植可能な方法

これはから来たものですPerlプログラミング、第4版。これはPerlスクリプトの実行に関するものです。

最後に、残念ながら#!魔法をサポートしていない古代のUnixシステムを使用している場合。行またはインタプリタパスが32文字を超える場合(多くのシステムでは組み込み制限)、次のように解決できます。

#!/bin/sh -- # perl, to stop looping
eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
if 0;

何が起こっているのかを段階的に説明できますか?私はそれを動作させたり含めたりしようとしましたが、役に立ちませんでした。

上記の操作を実行すると、次の結果が表示されます。

/bin/sh: 0: Illegal option --

ベストアンサー1

アイデアは、evalコマンドがシェルとPerlの両方で動作することです。違いは、改行がシェルでコマンドを終了しますが、Perlではコマンドを終了しないことです。代わりに、Perl は条件を追加する次の行を読み取り、コマンド全体if 0を効果的に無効にします。

next if $_ == 0(Perlはこれらの「逆方向」構成のいくつかの短縮型をサポートしています。たとえば、代わりにまたはif ($_ == 0) { next }代わりprint for @aに書くことができますfor (@a) { print }。)

スクリプトがシェルによって開始されると、シェルはそれを処理し、スクリプト名()とその引数()を引数として指定してevalPerlソルバーに置き換えます。$0$@

その後、Perlは実行し、読み込みeval、スキップし、if 0スクリプトの残りの部分に進みます。


これがうまくいく方法です。実際には2つの理由でエラーが発生します。 1)Perlがhashbang行自体を読むことと2)Linuxがhashbang行を処理する方法です。

Perlがハッシュバンを使用してスクリプトを実行すると、実際にはコメントとして扱われません。代わりに、ハッシュバンでPerlに与えられたすべてのオプション(あなたが持つことができるもの#!/usr/bin/perl -Wlnなど)を解釈します。しかし、ソルバーをチェックし、Perlによって実行されるべきではない場合は、スクリプトを実行します!

この試み:

$ cat > hello.sh
#!/bin/bash
echo $BASH_VERSION 
$ perl hello.sh
4.4.12(1)-release

実際にBashを実行します。

したがって、コメントは#perlPerlにとってはい、これは実際にPerlによって実行され、シェルが起動しないようにする必要があると言っています。再び

ただし、Linuxはインタプリタ名の後のすべてのエントリを単一の引数として提供するため、スクリプトを実行すると/bin/sh2つの引数-- # perl, to stop loopingで実行されますscriptname.pl。最初はダッシュで始まりますが、そうではない--ので、DashとBashの両方をオプションとして解釈しようとしています。無効であるため、bash ---またはを実行しようとしてエラーが発生しますbash "-- #perl"

他のシステムでは、hashbang行からパラメータを分離すると、シェルはという名前-- #perlのコマンドを見つけようとしますが、--これは機能しません。しかし、明らかに、行でシンボルをコメントマークとして扱うか、最初の引数だけを渡すシステムがいくつかありました。 (望むより#perl#perl##!これに関するSven Mascheckのページ.) これらのシステムでは動作します。


もう少し良い仕事があります。perlrun(適応):

#!/usr/bin/perl
eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
    if $running_under_some_shell;
print("Perl $^V\n");

これを実行すると、bash ./script.pl実際にPerlが実行され(たとえば)印刷されますPerl v5.24.1。 ($running_under_some_shellデフォルトではfalseに設定されている未定義の変数です。明確になりますが、if 0説明は少なくなります。)


あなたの引用が示すように、これらすべては#!正しく機能しない古代のシステムでのみ必要です。場合によってはまったくサポートされておらず、常にシェルで実行するには、バイナリではなくファイルを実行するシェルが必要です。他の場合には、ハッシュバンラインのパス長が制限されているので#!/really/veeeery/long/path/to/perl動作しません。

#!/usr/bin/perl最新のシステムにハッシュバンをインストールするだけです。

おすすめ記事