argvにプログラム名が含まれているのはなぜですか?

argvにプログラム名が含まれているのはなぜですか?

一般的なUnix / Linuxプログラムは、コマンドライン入力を引数数(int argc)と引数ベクトル(char *argv[])として受け入れます。最初の要素argvはプログラム名で、その後に実際のパラメータが続きます。

プログラム名が実行可能ファイルに引数として渡されるのはなぜですか?自分の名前を使用するプログラムの例はありますか(多分exec状況に応じて)?

答え1

まず、必ずしもargv[0]プログラム名である必要はないことに注意してください。これは、呼び出し側がargv[0]システムコールに入れることですexecve(例を参照)。スタックオーバーフローに関するこの質問)。 (他のすべてのバリエーションはexecシステムコールではなくインターフェイスですexecve。)

たとえば、次の状況を想定します(使用execl)。

execl("/var/tmp/mybackdoor", "top", NULL);

/var/tmp/mybackdoorは実行されますが、argv[0]に設定されますtop。これはpsまたは(実際)top表示されます。バラよりこの回答詳しくはU&L SEをご覧ください。

すべてを除いて:/procargv[0]利点は何ですか?

  • 一部のプログラムは、呼び出される名前に基づいて名前が付けられます(通常はシンボルまたはハードリンクを介して)。BusyBoxユーティリティ;この質問に対する他の答えには、より多くの例があります。
  • さらに、syslogを介して記録されたサービス、デーモン、および他のプログラムはしばしばログエントリに名前を追加するため、イベント追跡はほとんど不可能です。

答え2

適切:

  • バッシュは引き続き実行されますPOSIXモードいつ。argv[0]で始まるshと、argv[0]ログインシェルとして実行されます-
  • viviewVimは、、、、、などで動作しているときは異なる動作をしevimます。eviewexvimdiff
  • すでに述べたように、Busybox。
  • systemdをinitとして使用するシステムでは、などがありますshutdownrebootシンボリックリンクsystemctl
  • など。

答え3

歴史的には、argvこれはコマンドラインの「単語」へのポインタ配列であったので、プログラム名であった最初の「単語」で始まるのが合理的でした。

そして、呼び出しに使用された名前によって異なる動作をするプログラムがかなりたくさんあるので、そのプログラムへの別のリンクを作成して別の「コマンド」を得るだけです。私が考える最も極端な例は次のとおりです。忙しい箱、どちら呼び出し方法に応じて、何十もの異なる「コマンド」のように動作します。

編集する:リクエスト時にUnixの最初のバージョンに関する参考資料を提供する

たとえば、次から始めることができます。基本ccこの機能は使用されargcていargvません。これシェルループセクション内にパラメータをコピーしparbufnewargコマンド自体もパラメータと同じ方法で処理します。 (もちろん、後にはコマンド名である最初の引数だけを実行します。)execv当時は親戚が存在しなかったようです。

答え4

プログラムの呼び出し方法に応じて動作を変更することに加えて、argv[0]印刷プログラムを次のように使用すると便利です。

printf("Usage: %s [arguments]\n", argv[0]);

これにより、消費メッセージは常に呼び出された名前を使用します。プログラム名が変更されると、使用情報も変更されます。これには、呼び出されたパス名も含まれます。

# cat foo.c 
#include <stdio.h>
int main(int argc, char **argv) { printf("Usage: %s [arguments]\n", argv[0]); }
# gcc -Wall -o foo foo.c
# mv foo /usr/bin 
# cd /usr/bin 
# ln -s foo bar
# foo
Usage: foo [arguments]
# bar
Usage: bar [arguments]
# ./foo
Usage: ./foo [arguments]
# /usr/bin/foo
Usage: /usr/bin/foo [arguments]

これは、特にさまざまな場所に散在している可能性がある小さなプロフェッショナルツール/スクリプトの場合に良いタッチです。

これはGNUツールでも一般的な慣行のようですls。たとえば、次のようになります。

% ls --qq
ls: unrecognized option '--qq'
Try 'ls --help' for more information.
% /bin/ls --qq
/bin/ls: unrecognized option '--qq'
Try '/bin/ls --help' for more information.

関連情報