16

私たちは先生の解釈に多くの問題を抱えています。私たちは説明を求め、彼から次のことを返しました

  1. execveの場合は、エクスポートされた変数を使用してセットアップした環境を送信し、組み込みコマンドを作成して/ bin / bashのサブシェルを生成します。これにより、envを使用してエクスポートされた変数を確認できます。

    (彼はここで独自の環境変数を作成することについて話しています。)

  2. はい、自分で作成します。シェルの起動時にenvironをコピーして、エクスポートされた変数のみを追加することから始めることができます

これは、私によるStack Overflowに関する次の投稿に関連しています(この他の投稿を読むと、私がやろうとしていることを理解するのに役立ちます):

execveで新しいパスを使用してlsコマンドを実行する

私たちはこれについて非常に混乱しています。もう一度、私たちが今やろうとしていることを説明します。Linuxシェルがこれを行う方法と同様に、PATHやUSERなどの環境変数や、ユーザーが定義したいその他の変数を設定できる独自のプログラムを作成する必要があります。

これをどのように呼び出すかの例は、(プログラム内のプロンプトで)次のようになります。

mysetenv dog spike

これにより、「dog=spike」のような環境変数が作成されます。

execさらに重要なのは、独自のPATH変数を設定し、それをコマンドに送信できる必要があることです。これは紛らわしい部分です。なぜなら、私たちのすべての質問に基づいて、私たちが何をすべきかを理解していないからです。

4

3 に答える 3

42

それは実際には非常に簡単です。引数が のリストでありchar *、NULL ポインターで終了していることは既にわかっています。同様に、環境は単に のリストでありchar *、NULL ポインターで終了します。通常、リスト内の値は の形式を取りVARNAME=var-valueますが、必要に応じて他の形式を渡すこともできます。

したがって、単純なケースを取り上げると、次のようになります。

#include <unistd.h>
#include <stdio.h>

int main(void)
{
    char *argv[] = { "/bin/sh", "-c", "env", 0 };
    char *envp[] =
    {
        "HOME=/",
        "PATH=/bin:/usr/bin",
        "TZ=UTC0",
        "USER=beelzebub",
        "LOGNAME=tarzan",
        0
    };
    execve(argv[0], &argv[0], envp);
    fprintf(stderr, "Oops!\n");
    return -1;
}

この例では、プログラムは/bin/sh引数-cおよびenvで実行されます。これは、シェルがenv現在の PATH にあるプログラムを実行することを意味します。ここでの環境は、オーソドックスな形式で 5 つの値を含むように設定されています。(または) に変更envすると、たとえば TZ 設定の効果が表示されます。MacOS X マシンでそれを実行すると、出力は次のようになります。dateenv; date

USER=beelzebub
PATH=/bin:/usr/bin
PWD=/Users/jleffler/tmp/soq
TZ=UTC0
SHLVL=1
HOME=/
LOGNAME=tarzan
_=/usr/bin/env

シェルは環境変数を追加SHLVLし、呼び出しで明示的に設定したものに_追加しました。PWDexecve()

明示的に設定したいものと競合しない本物の環境から他の環境変数のいくつかをコピーするなど、より手の込んだこともできます。また、環境内の 1 つの変数に対して 2 つの値を持つようなゲームをプレイすることもできます。どちらが有効ですか? また、スペースを含む変数名 (シェルはあまり好まない) や、'varname=value' 表記にまったく一致しない (等号がない) エントリでゲームをプレイできます。

于 2011-10-05T05:48:13.067 に答える
8

ここでのパーティーには少し遅れましたが、古い環境変数を保持し、独自の環境変数を作成したい場合は、 を使用してからsetenvに渡します。environexecve()

    setenv("dog", "spike", 1);
    extern char** environ;
    execve(argv[0], argv, environ);

environは で宣言された変数でunistd.hあり、この実行中のプロセス中に環境変数を追跡します。

setenv()putenv()変更するenvironので、それを渡すとexecve()、環境変数は期待どおりになります。

于 2016-08-22T20:15:42.557 に答える
1

Jonathan Lefflerのコードは、 PWD(作業ディレクトリ) 変数を変更する場合を除いて、うまく機能します。

作業ディレクトリを変更するために私がしたことは、chdir(..)前に置いてexecve(..)呼び出すことでした:

chdir("/foo/bar"); 
execve(argv[0], &argv[0], envp);
于 2012-08-28T11:25:16.633 に答える