myprg
の代わりに それがシバンで使用されているかどうかを魔法のように検出します。コマンドライン フラグ (-f
など) を使用して明示的にしないでください。 ) スクリプトとしてファイルを渡しますか?
コメントの例から:
<ブロック引用>
上記の calc の理論的な例では。 calc PI + 1
4.14159 を返す必要があります... シバン (つまり、最初のパラメーターとしてファイル名) のサポートを追加すると、ファイルに含まれる計算が返されます。
calc
にする -f
までのスクリプト ファイルを取得する 次にスクリプトを作成します:
#!/usr/local/bin/calc -f
$1 + 1
このファイルを addone.calc
と呼ぶとしましょう そして実行可能にします。次に、次のように呼び出すことができます:
$ ./addone.calc PI
4.141592...
その呼び出しは /usr/local/bin/calc -f ./addone.calc PI
の呼び出しに変換されます であるため、どの引数がスクリプト ファイルで、どの引数がスクリプトへのパラメーターであるかは明らかです。
これは awk
に似ています と sed
同様の (しかし反対の) アプローチは calc
を持つことです デフォルトでスクリプトファイルの引数を取りますが(これにより、シバンでの使用が簡素化されます)、コマンドラインフラグを追加して、引数からの式で使用します。これは sh -c '...'
に似ています
本当の問題は、 <mypgm>
のコマンドライン構文を設計した方法です .その引数を解釈する 2 つの方法をサポートしようとする代わりに、代わりにそれを呼び出す 2 つの方法を提供します。
Shebang コマンドは、スクリプトのコンテンツを実行するスクリプト エンジンを意図しています。 bash
かもしれません 、 perl
、またはその他のものですが、実行するスクリプトのファイル名で呼び出されることが期待されています。 bash
はどのように機能しますか やれ?それは推測しません。オプション (またはオプションの引数) のように見えない引数に遭遇すると、それを実行するスクリプトとして扱います。その後の引数はスクリプトに渡されます。例:
/bin/bash -x -e somename foo bar
ここで、bash はファイル somename
を探します。 引数 foo
を持つスクリプトとして実行してみてください と bar
. 可能性があるため、同じことを行う必要があります。 <mypgm> <myscript>
を書きたい いつかコマンドラインで。
<mypgm>
をスクリプトなしで使用したい場合 デフォルトにするには、スクリプトを <mypgm> -f <myscript>
で渡すように要求できます .これが sed
のやり方です それをします。次に、次のようなシバン行で使用します:
#!<mypgm> -f
bash
のようにスクリプトケースをデフォルトにしたい場合 と perl
、「今回はスクリプトはありません」というオプションを作成します。 --
を使用できます このため、 <mypgm> -- one two three
one
を実行しようとしません (またはその他のもの)スクリプトとして。その場合、シバン行は次のようになります:
#!<mypgm>
<ブロック引用>
ここで、シバンを使用して blabla が呼び出されたかどうかを知る必要があります。
C では、getauxval(AT_EXECFN)
を介してその情報を取得できます。 、元の実行可能ファイルの名前がわかります (つまり、execve(2)
に渡される最初の引数) ) [1].
しかし、その文字列は、コマンド ライン引数と環境文字列の直後、[stack]
の最後に配置されます。 そこから直接フェッチできるようにします。
たとえば、次の perl スクリプト (名前は foo.pl
)、chmod 755 foo.pl
で実行可能にした場合 、 ./foo.pl
を出力します 直接実行すると /usr/bin/perl
perl ./foo.pl
として実行した場合 :
#! /usr/bin/perl
open my $maps, "/proc/self/maps" or die "open /proc/self/maps: $!";
my $se;
while(<$maps>){ $se = hex($1), last if /^\w+-(\w+).*\[stack\]$/ }
open my $mem, "/proc/self/mem" or die "open /proc/self/mem: $!";
sysseek $mem, $se - 512, 0;
sysread $mem, $d, 512 or die "sysread: $!";
print $d =~ /([^\0]+)\0+$/, "\n";
新しい (>=3.5) Linux カーネルでは、環境の終わりも /proc/PID/stat
で利用できます。 (proc(5)
に記載されているように、51 番目のフィールドで マンページ)
#! /usr/bin/perl
open my $sh, "/proc/self/stat" or die "open /proc/self/stat: $!";
my @s = <$sh> =~ /\(.*\)|\S+/g;
open my $mem, "/proc/self/mem" or die "open /proc/self/mem: $!";
seek $mem, $s[50], 0;
$/ = "\0";
my $pn = <$mem> or die "readline: $!"; chomp $pn; print "$pn\n";
[1] 2.6.26 より新しい Linux カーネルでは、それを指す aux ベクトル エントリが導入されましたが (コミットを参照)、実行可能ファイル名はそれよりずっと前にスタックの最後で利用可能でした (1996 年の linux-2.0 以降)。