GNU/Linux >> Linux の 問題 >  >> Linux

シバンまたはシバンではない

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 以降)。


Linux
  1. mkfs:コマンドが見つかりません

  2. ファイル:コマンドが見つかりません

  3. tune2fs:コマンドが見つかりません

  1. fsck:コマンドが見つかりません

  2. tail:コマンドが見つかりません

  3. touch:コマンドが見つかりません

  1. 並べ替え:コマンドが見つかりません

  2. sed:コマンドが見つかりません

  3. アトミック作成ファイルが存在しない場合は、bash スクリプトから