追加読書

追加読書

一般化する

mirageshebangで始まるPythonプログラムを例にしてみましょう。

#!/usr/bin/python
...

見たり/proc/<pid>/comm使ったりするpgrep姿は…

...shebangを介して呼び出すと、プロセス名は "mirage"です。

/usr/bin/mirage &

...しかし、明示的にPythonを呼び出すと「python」になります。

/usr/bin/python /usr/bin/mirage &
  • プロセスが自分の名前を変更できることを知っていますが、2つのケースの名前が異なるのはなぜですか?
  • /procプロセスが最初に始まる方法(単に使用またはgrep情報を使用)を理解する一般的な方法はありますか?

詳細 - シェボン

/home/martin> /usr/bin/mirage &
[1] 22638

/proc/<pid>/commそれを「蜃気楼」と呼んでください。

/home/martin> cat /proc/22638/comm 
mirage

パッケージ「蜃気楼」であることが確認されましたが、「Python」ではありません。

/home/martin> pgrep -al mirage && echo "found" || echo "not found"
22638 /usr/bin/python /usr/bin/mirage
found

/home/martin> pgrep -al python && echo "found" || echo "not found"
not found

詳細 - Python

/home/martin> /usr/bin/python /usr/bin/mirage &
[1] 21348

/proc/<pid>/comm「Python」と呼んでください

/home/martin> cat /proc/21348/comm 
python

パッケージ「python」ですが、「mirage」ではないことがわかりました。

/home/martin> pgrep -al mirage && echo "found" || echo "not found"
not found

/home/martin> pgrep -al python && echo "found" || echo "not found"
21348 /usr/bin/python /usr/bin/mirage
found

答え1

プロセス名はargv[0]呼び出しから派生しますexecv()

これは観察された動作を説明します。

実際、shebangの場合、カーネルはベクトルに影響を与えずに呼び出される方法を並べ替えますargv

答え2

プロセスが自分の名前を変更できることを知っていますが、2つのケースの名前が異なるのはなぜですか?

関連する手順が異なるためいいえ名前を変更してください。 Linuxのデフォルトの動作に応じて、割り当てられた名前が割り当てられます。 (他のオペレーティングシステムは動作が異なりますが、これはファイルに関するものなのでLinuxの質問です/proc/*/comm。)

Linuxでは、プログラム名は次のcommいずれかから取得されます。プログラムイメージファイル渡される名前はexecve()次のとおりです。この点に注意してくださいいいえ引数ベクトルまたは環境ベクトルであり、Linuxの引数ベクトルから名前を取得したという内容が正しくありません。

シェルが実際に渡したプログラムイメージファイル名は/usr/bin/pythonsum/usr/bin/mirageなので、pythonsumは初期化された内容mirageです。/proc/self/commcommプログラムイメージファイル名のデフォルト名は切り捨てられます。)

パラメータベクトルはプロセスの内容を初期化し/proc/self/cmdline、環境ベクトルはその内容を初期化します/proc/self/environ。したがって、これらの合計を使用し/proc/self/commてプログラムの実行中にそれを変更しないと仮定すると、3つの情報がすべて渡され、execve()「プロセスが最初に開始された方法」を正確に知ることができます(厳密に言えばこれは方法です)。プログラムなどがリリースされました。プロセス)で始めてくださいfork()

以下は、説明のために小さな環境と力を設定するためにnoshツールセットでclearenv使用する3つの部分の実際の例です。setenvexecargv[0]

%clearenv setenv 1THIS '環境文字列です。' setenv 2COMPRISING' すべての環境です。 \
> exec -a 'argv[0]。 ' /bin/sleep 100 &
[1]15564
% for i in /proc/$\!/{comm,cmdline,environ} ; printf "%s:" $i 実行 printf "\n" ;
/proc/15564/通信:3

/proc/15564/cmdline:argv[0] です。^@100^@
/proc/15564/environ:1THIS=環境文字列^@2COMPRISING=すべての環境。 ^@
%

実際にはこれexec。 (内部的にはフォームプログラムイメージファイル名を使用するCライブラリ関数を使用するためです。)execve()/bin/sleep3execfexecve()/proc/self/fd/3

プログラムイメージファイルは、名前付きインタプリタと#!インタプリタにプログラムイメージファイルを置き換えて引数ベクトルを移動させるマジック番号を持つスクリプトです。変更なし何が入りますかcomm?元々提供されたプログラムイメージファイル名はそのまま残りますexecve()。はい、Linuxはここで一貫性がありません。するこの場合、内容をcmdline有効な最終パラメータ文字列に変更します。

追加読書

関連情報