この回答は少し遅れるかもしれませんが、私は同じ問題を抱えており、受け入れられた回答は私にはあまり満足のいくものではなかったので、もう少し調査しました。
私を悩ませたのは、ユーザーが入力した内容に関する正しい情報を実際に保持していない、$0または$PROGRAM_NAME保持していないという事実でした。RubyスクリプトがPATHフォルダーにあり、ユーザーが実行可能ファイル名を入力した場合(./scriptまたはなどのパス定義なしで/bin/script)、常に合計パスに展開されます。
これはRubyの不足だと思ったので、Pythonでも同じことを試してみましたが、残念ながら違いはありませんでした。
友人が私にreal thinginを探すためのハックを提案/proc/self/cmdlineし、結果は次のようになりました:([ruby, /home/danyel/bin/myscript, arg1, arg2...]ヌル文字で区切られています)。ここでの悪役execve(1)は、パスをインタプリタに渡すときに、パスを合計パスに拡張します。
Cプログラムの例:
extern char** environ;
int main() {
char ** arr = malloc(10 * sizeof(char*));
arr[0] = "myscript";
arr[1] = "-h";
arr[2] = NULL;
execve("/home/danyel/bin/myscript", arr, environ);
}
出力: ʻ使用法:/ home / danyel / bin / myscript FILE .. ..
これが実際にexecvebashからのものではなく、物であることを証明するために、渡された引数を出力するだけのダミーインタープリターを作成できます。
// interpreter.c
int main(int argc, const char ** argv) {
while(*argv)
printf("%s\n", *(argv++));
}
それをコンパイルしてパスフォルダーに入れ(またはシバンの後にフルパスを入れて)、ダミースクリプトを作成します ~/bin/myscript/
Hi there!
今、私たちのmain.cで:
extern char** environ;
int main() {
char ** arr = malloc(10 * sizeof(char*));
arr[0] = "This will be totally ignored by execve.";
arr[1] = "-v";
arr[2] = "/var/log/apache2.log";
arr[3] = NULL;
execve("/home/danyel/bin/myscript", arr, environ);
}
コンパイルと実行./main:インタープリター/ home / danyel / bin / myscript -v /var/log/apache2.log
この背後にある理由は、スクリプトがPATHにあり、フルパスが指定されていない場合、インタープリターがこれをNo such fileエラーとして認識するためです。エラーが発生した場合は、次のように認識されruby myrubyscript --options arg1ます。そのスクリプトのフォルダーにいない場合。