0

これは、私のオペレーティングシステムクラスの宿題の説明からの抜粋です。太字の部分は私には理解できない部分であり、今は教授に連絡することもできません。今夜から始めたいと思います。私は環境変数が何であるかを知っています、私は推測します...シェルで宣言された変数だけですよね?しかし、特に太字の線はどういう意味ですか?

ユーザーがコマンドを実行する対話型シェルを実装するCプログラムを作成します。

このプログラムをmyshellと呼びます(したがって、gcc -o myshell -Wallなどを使用してコンパイルします)。

ユーザーにコマンドの入力を繰り返し求める無限ループを作成します(以下の出力と入力の例を参照)。

ユーザーが入力したコマンドを実行する前に、環境変数THEPATHで指定されたパスを使用してコマンドを見つける必要があります(PATHは使用しないでください)。デフォルトでは、THEPATH変数は設定されていないため、テストでは、この変数を手動で設定(および設定解除)する必要があります(以下の詳細を参照)。THEPATHが見つかった場合、プログラムはfork()およびexec()システムコールの1つを介して子プロセスでコマンドを実行する必要があります。

THEPATHを取得して解析するには、getenv()関数とstrtok()またはstrsep()関数の使用を検討してください。

4

3 に答える 3

1

シェルがプログラムを実行するには、そのプログラムがどこにあるかを知る必要があります。たとえばls、プロンプトで入力できるようにしたいが、 の実際のバイナリが にlsある可能性があります/bin/ls。ここでPATH(またはあなたの場合はTHEPATH) の出番です。 と入力するlsと、シェルがオフになり、各PATHディレクトリで一致する名前のプログラムを探します。見つかったら、それを実行します。ls例として、PATH次のように設定してみましょう。

/usr/local/bin:/usr/bin:/bin

が であると仮定するls/bin/ls、シェルは最初にlsin/usr/local/binを探し、見つからず、次に in を調べ、/usr/bin最後に in を見つけて/bin実行します。

実際にこの操作を行うgetenvことで、 、strtok、およびに関する割り当てのヒントが得られますstrsep

于 2012-09-30T03:04:35.160 に答える
0

遅れたことは承知していますが、マスター フーの「コーディングしないことでメリットを得る」という精神に基づいて、ここで汚いトリックを行うことができます。、およびC ライブラリ関数はexeclp()、実際に PATH 変数を検索します。環境内で PATH を THEPATH に置き換えるだけです。すべての子プロセスが元の THEPATH を PATH として使用するため、シェルもより安全になります。execvp()execvpe()

int i_path = -1;
int i_thepath = -1;
int i = 0;
while (envp[i] != NULL) {
    if (strstr(envp[i], "PATH=") == envp[i])
        i_path = i;
    if (strstr(envp[i], "THEPATH=") == envp[i])
        i_thepath = i;
    i++;
}
if (i_path >= 0 && i_thepath >= 0)
    envp[i_path] = envp[i_thepath] + 3; /* discard 'THE' */
else if (i_thepath >= 0)
    envp[i_thepath] = envp[i_thepath] + 3; /* discard 'THE' */
execvpe(command, argv, envp);

THEPATH を手動で解析する場合は、ディレクトリのリストを作成しないでください。Perl のような高水準言語では簡単ですが、THEPATH に dir 要素がいくつあるか事前にわからないため、C では手動で動的メモリを割り当てる必要があります。メモリ割り当てを行うには、最初に文字列を反復処理する必要があります。strtok()ただし、最初の繰り返しでwith":"をセパレータとして使用することで、実際の作業を行うことができます。

char *thepath = envp[i_thepath];
char *dir;
strtok(thepath, "="); /* first discard 'THEPATH=' */
while (dir = strtok(NULL, ":") {
    /* now check if dir+command exists and is execuatble, exec */
}
于 2013-09-04T06:45:26.837 に答える
0

変数THEPATHには、次のようにコロンで区切られたディレクトリのリストが含まれている必要があります。

THEPATH=/usr/bin:/bin:some-other-dirs

これをディレクトリのリストに解析する必要があります。ユーザーがコマンドを入力すると、ユーザーが入力したコマンドと名前が一致する実行可能ファイルを見つけるために、すべてのディレクトリをスキャンする必要があります。

このレベルの洗練されたシェルを作成することは、初心者向けの作業ではありません。システムの PATH 処理がどのように機能するかを理解していない場合 (シェルの動作をエミュレートしているだけです)、頭がおかしくなっている可能性があります。

于 2012-09-30T03:04:01.410 に答える