「env」と「printenv」の違いは何ですか?


67

2つのコマンドenvととの違いは何printenvですか?どちらも環境変数を示しており、出力はを除いてまったく同じ_です。

1つではなく2つのコマンドがあるという歴史的な理由はありますか?

回答:


49

1つではなく2つのコマンドがあるという歴史的な理由はありますか?

ただ歴史的なマナーがありました。

  1. ビル・ジョイはprintenv1979年にBSD用のコマンドの最初のバージョンを書きました。
  2. UNIX System III envは1980年にコマンドを導入しました。
  3. GNU envは1986年にUNIXシステムに続きました。
  4. env1988年、BSDはGNU / UNIXシステムに準拠しました。
  5. printenv1988年にMINIXはBSDに準拠しました。
  6. GNU printenvは1989年にMINX / BSDに続きました。
  7. GNUのシェルプログラミングユーティリティ含ま1.0 printenvenv1991インチ
  8. GNU Shell Utilitiesは2002年にGNU coreutilsに統合されました。これは、最近のGNU / Linuxで簡単に見つけることができたものです。

「フォロー」はソースコードが同じであることを意味しないことに注意してください。おそらくライセンス訴訟を避けるためにソースコードが書き直されました。

両方のコマンドが存在した理由は、ビル・ジョイがprintenvその時間を書いたとき、envまだ存在していないためです。10年のマージ/互換性とGNUがそれに遭遇した後、同じページに両方の同様のコマンドが表示されています。

この履歴は次のように示されています:( 答えを最小化しようとしているため、ここでは2つの必須ソースコードのみを提供し、残りは添付のリンクをクリックして表示します)

[1975年の秋]

1975年の秋には、2人の見知らぬ大学院生、ビルジョイとチャックヘイリーも到着しました。彼らは両方とも新しいシステムにすぐに興味を持ちました。当初、彼らはトンプソンが11/70の機械室をぶらぶらしているときに一緒にハッキングしたPascalシステムの開発を始めました。

[1977]

Joyは、1978年3月9日にリリースされた最初のBerkeley Software Distribution(1BSD)のコンパイルを開始しました。// rf:https : //en.wikipedia.org/wiki/Berkeley_Software_Distribution

[1979年2月]

1979(「ビルジョイ、1979年2月」を参照)/ 1980(「copyright [] = "を参照)」、printenv.c // rf:http ://minnie.tuhs.org/cgi-bin/utree.pl ? file = 2.11BSD / src / ucb / printenv.c

/*
 * Copyright (c) 1980 Regents of the University of California.
 * All rights reserved.  The Berkeley software License Agreement
 * specifies the terms and conditions for redistribution.
 */

#ifndef lint
char copyright[] =
"@(#) Copyright (c) 1980 Regents of the University of California.\n\
 All rights reserved.\n";
#endif not lint

#ifndef lint
static char sccsid[] = "@(#)printenv.c  5.1 (Berkeley) 5/31/85";
#endif not lint

/*
 * printenv
 *
 * Bill Joy, UCB
 * February, 1979
 */

extern  char **environ;

main(argc, argv)
    int argc;
    char *argv[];
{
    register char **ep;
    int found = 0;

    argc--, argv++;
    if (environ)
        for (ep = environ; *ep; ep++)
            if (argc == 0 || prefix(argv[0], *ep)) {
                register char *cp = *ep;

                found++;
                if (argc) {
                    while (*cp && *cp != '=')
                        cp++;
                    if (*cp == '=')
                        cp++;
                }
                printf("%s\n", cp);
            }
    exit (!found);
}

prefix(cp, dp)
    char *cp, *dp;
{

    while (*cp && *dp && *cp == *dp)
        cp++, dp++;
    if (*cp == 0)
        return (*dp == '=');
    return (0);
}

[1979]

2BSDまたは3BSD // rfでリリースされたと判断するのは難しい:https : //en.wikipedia.org/wiki/Berkeley_Software_Distribution

  • 3BSD printenvコマンドは3.0 BSDで登場しました。// rf:http ://www.freebsd.org/cgi/man.cgi ? query = printenv&sektion=1#end 3.0 1979年に導入されたBSD // rf:http : //gunkies.org/wiki/3_BSD

  • 2BSD printenvコマンドは2BSD // rfで初めて登場しました:http ://man.openbsd.org/printenv.1

[1980年6月]

UNIXリリース3.0または「UNIX System III」// rf:ftp : //pdp11.org.ru/pub/unix-archive/PDP-11/Distributions/usdl/SysIII/

[xiaobai@xiaobai pdp11v3]$ sudo grep -rni printenv . //no such printenv exist.
[xiaobai@xiaobai pdp11v3]$ sudo find . -iname '*env*'
./sys3/usr/src/lib/libF77/getenv_.c
./sys3/usr/src/lib/libc/vax/gen/getenv.c
./sys3/usr/src/lib/libc/pdp11/gen/getenv.c
./sys3/usr/src/man/man3/getenv.3c
./sys3/usr/src/man/docs/c_env
./sys3/usr/src/man/docs/mm_man/s03envir
./sys3/usr/src/man/man7/environ.7
./sys3/usr/src/man/man1/env.1
./sys3/usr/src/cmd/env.c
./sys3/bin/env
[xiaobai@xiaobai pdp11v3]$ man ./sys3/usr/src/man/man1/env.1 | cat //but got env already
ENV(1)                                                                General Commands Manual                                                                ENV(1)



NAME
       env - set environment for command execution

SYNOPSIS
       env [-] [ name=value ] ...  [ command args ]

DESCRIPTION
       Env obtains the current environment, modifies it according to its arguments, then executes the command with the modified environment.  Arguments of the form
       name=value are merged into the inherited environment before the command is executed.  The - flag causes the inherited environment to be ignored  completely,
       so that the command is executed with exactly the environment specified by the arguments.

       If no command is specified, the resulting environment is printed, one name-value pair per line.

SEE ALSO
       sh(1), exec(2), profile(5), environ(7).



                                                                                                                                                             ENV(1)
[xiaobai@xiaobai pdp11v3]$ 
[xiaobai@xiaobai pdp11v3]$ cat ./sys3/usr/src/cmd/env.c //diff with http://minnie.tuhs.org/cgi-bin/utree.pl?file=pdp11v/usr/src/cmd/env.c version 1.4, you will know this file is slightly older, so we can concluded that this file is "env.c version < 1.4"
/*
 *      env [ - ] [ name=value ]... [command arg...]
 *      set environment, then execute command (or print environment)
 *      - says start fresh, otherwise merge with inherited environment
 */
#include <stdio.h>

#define NENV    100
char    *newenv[NENV];
char    *nullp = NULL;

extern  char **environ;
extern  errno;
extern  char *sys_errlist[];
char    *nvmatch(), *strchr();

main(argc, argv, envp)
register char **argv, **envp;
{

        argc--;
        argv++;
        if (argc && strcmp(*argv, "-") == 0) {
                envp = &nullp;
                argc--;
                argv++;
        }

        for (; *envp != NULL; envp++)
                if (strchr(*envp, '=') != NULL)
                        addname(*envp);
        while (*argv != NULL && strchr(*argv, '=') != NULL)
                addname(*argv++);

        if (*argv == NULL)
                print();
        else {
                environ = newenv;
                execvp(*argv, argv);
                fprintf(stderr, "%s: %s\n", sys_errlist[errno], *argv);
                exit(1);
        }
}

addname(arg)
register char *arg;
{
        register char **p;

        for (p = newenv; *p != NULL && p < &newenv[NENV-1]; p++)
                if (nvmatch(arg, *p) != NULL) {
                        *p = arg;
                        return;
                }
        if (p >= &newenv[NENV-1]) {
                fprintf(stderr, "too many values in environment\n");
                print();
                exit(1);
        }
        *p = arg;
        return;
}

print()
{
        register char **p = newenv;

        while (*p != NULL)
                printf("%s\n", *p++);
}

/*
 *      s1 is either name, or name=value
 *      s2 is name=value
 *      if names match, return value of s2, else NULL
 */

static char *
nvmatch(s1, s2)
register char *s1, *s2;
{

        while (*s1 == *s2++)
                if (*s1++ == '=')
                        return(s2);
        if (*s1 == '\0' && *(s2-1) == '=')
                return(s2);
        return(NULL);
}
[xiaobai@xiaobai pdp11v3]$

[1985]

BSD first printenv manual // rf:http ://minnie.tuhs.org/cgi-bin/utree.pl?file=2.11BSD/src/man/man1/printenv.1 しかし、envに関連するマニュアルが見つかりません、最も近いのはgetenvとenviron // http://minnie.tuhs.org/cgi-bin/utree.pl?file=2.11BSD/src/man

[1986]

GNU env// rfの最初のバージョン:ftp : //ftp-archive.freebsd.org/pub/FreeBSD-Archive/old-releases/i386/1.0-RELEASE/ports/shellutils/src/env.c

[1987]

MINIX 1stリリース// rf:https : //en.wikipedia.org/wiki/Andrew_S._Tanenbaum

  • Tanenbaumは、IBM PC用にMINIX(MINi-unIX)と呼ばれるUNIXのクローンを作成しました。これは、オペレーティングシステムがどのように機能するかを学びたい学生やその他の人々を対象としています。

[1988]

BSD 1st env.c // http://minnie.tuhs.org/cgi-bin/utree.pl?file=2.11BSD/src/usr.sbin/cron/env.c

/* Copyright 1988,1990,1993,1994 by Paul Vixie
 * All rights reserved

[1988年10月4日]

MINIXバージョン1.3 // rf:https ://groups.google.com/forum/#!topic/comp.os.minix/ cQ8kaiq1hgI

... 32932 190 /minix/commands/printenv.c //printenv.cはすでに存在します

// rf:http : //www.informatica.co.cr/linux/research/1990/0202.htm

[1989]

GNUの最初のバージョンはprintenv、[1993年8月12日]を参照してください。

[1991年7月16日]

「Shellutils」-GNUシェルプログラミングユーティリティ1.0リリース// rf:https ://groups.google.com/forum/#!topic/gnu.announce/xpTRtuFpNQc

このパッケージのプログラムは次のとおりです。

basename date dirname env expr groups id logname pathchk printenv printf sleep tee tty whoami yes nice nohup stty uname

[1993年8月12日]

printenv.c // RF:ftp://ftp-archive.freebsd.org/pub/FreeBSD-Archive/old-releases/i386/1.0-RELEASE/ports/shellutils/src/printenv.c

、GNU Shell Utilities 1.8 // rf:ftp : //ftp-archive.freebsd.org/pub/FreeBSD-Archive/old-releases/i386/1.0-RELEASE/ports/shellutils/VERSION

/* printenv -- print all or part of environment
   Copyright (C) 1989, 1991 Free Software Foundation.
...

[1993]

2006年のDSLinuxソースコードで見つかったprintenv.c // rf:(Google)cache:mailman.dslinux.in-berlin.de/pipermail/dslinux-commit-dslinux.in-berlin.de/2006-August/000578。 html

--- NEW FILE: printenv.c ---
/*
 * Copyright (c) 1993 by David I. Bell

[1993年11月]

FreeBSDの最初のバージョンがリリースされました。// rf:https : //en.wikipedia.org/wiki/FreeBSD

[2002年9月1日]

http://git.savannah.gnu.org/cgit/coreutils.git/tree/README-package-renamed-to-coreutils

GNU fileutils、textutils、sh-utils(上記の1991年7月16日の「Shellutils」を参照)パッケージは、GNU coreutilsと呼ばれるものにマージされました。

全体的に、envユースケースは次と比較されprintenvます:

  1. 環境変数を出力しますがprintenv、同じことができます
  2. シェルの組み込みを無効にしますが、enablecmdでも実現できます。
  3. 変数を設定しますが、いくつかのシェルがなくてもそれを行うことができるため、無意味ですenv、例えば

    $ HOME = / dev HOME = / tmp USER = root / bin / bash -c "cd〜; pwd"

    / tmp

  4. #!/usr/bin/env pythonヘッダーですがenv、/ usr / binにない場合は移植できません

  5. env -i、すべての環境を無効にします。特定のプログラムを実行するための特定のプログラムの重要な環境変数を把握しておくと便利ですcrontab。例[1]インタラクティブモードでは、実行declare -p > /tmp/d.shして属性変数を保存します。[2]で/tmp/test.sh、書き込み:. /tmp/d.sh; eog /home/xiaobai/Pictures/1.jpg[3]今すぐ実行env -i bash /tmp/test.sh[4]イメージの表示に成功したら、変数の半分を削除して/tmp/d.shenv -i bash /tmp/test.shもう一度実行します。何かが失敗した場合は、元に戻します。手順を繰り返して絞り込みます。[5]最後に、で実行するeog必要があることがわかります。これがないと、画像の表示が遅くなります。$DISPLAYcrontab$DBUS_SESSION_BUS_ADDRESS

  6. target_PATH="$PATH:$(sudo printenv PATH)";envまたはの出力をさらに解析する必要なく、ルートパスを直接使用するのに便利ですprintenv

例えば:

xb@dnxb:~$ sudo env | grep PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
xb@dnxb:~$ sudo printenv | grep PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
xb@dnxb:~$ sudo printenv PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
xb@dnxb:~$ sudo env PATH
env: ‘PATH’: No such file or directory
xb@dnxb:~$

4
素敵な歴史のレッスン。
Ouki

21

(FreeBSDからの)別の視点を持っている、あなたが持っている:

からman env

 The env utility executes another utility after modifying the environment
 as specified on the command line.  Each name=value option specifies the
 setting of an environment variable, name, with a value of value.  All
 such environment variables are set before the utility is executed.
 ...
 If no utility is specified, env prints out the names and values of the
 variables in the environment, with one name/value pair per line.

からman printenv

 The printenv utility prints out the names and values of the variables in
 the environment, with one name/value pair per line.  If name is speci-
 fied, only its value is printed.

したがって、これらのコマンドは引数なしで同じ効果を持つ可能性がありますが、printenv唯一の目的は、現在の環境のキー/値を表示するenvことです。

この方法はより明確ですか?

もっと知るには:


2
提供されたリンクから:コマンドは、4.4BSDで登場しました。-P、-S、および-vオプションは、FreeBSD 6.0で追加されました。このコマンドは3.0BSDで登場しました。したがって、歴史的な理由は、最初に到着したことのようです。env printenvprintenv
mcmlxxxvi


3

マンページから:

env-変更された環境でプログラムを実行する

...

printenv-環境の全部または一部を出力します

かなり説明的なはずです。


4
しかし、私はそれが...得ることはありません
mikeserv

envはprintenvの前に来ると思います。では、なぜ別のバイナリを作成するのですか?「ll」はバイナリではなく、manページがないため、これは「ll」から「ls」と同じではありません。
WiSaGaN 14

@mikeserv printenvは、現在の環境のすべての変数を出力するだけです。ではenv、あなたは必要に応じていくつかの変更と同じ環境を用意し、その中にアプリを実行することができます。
UVV 14

@WiSaGaNの比較は実際には正しくありません。lsはバイナリllですが、一般的なエイリアスであり、通常は単にに展開されls -lます。2つの異なるバイナリがprintenvありenvますが、どちらが最初に導入されたかはわかりません。あなたはここにいくつかのより多くの例を見ることができますgnu.org/software/coreutils/manual/html_node/env-invocation.html
UVV

1
@mikeserv、このコミックのマウスオーバーテキストを参照してください。:)
ワイルドカード

3

機能について厳密に言うと、機能envの巨大なセットを持つバイナリであり、その1つは環境変数を印刷するのに対して、環境変数を印刷するprintenvだけです。

要約すると、envでの作業に慣れている場合はenv(これが慣れているからです)印刷に進みます。そうでない場合は、通常printenvより速く覚えられます。

話をするときに差は事実上ありませんprintenvVS envだけの環境変数を印刷します。確認したところ、envはわずかに重く(約5 KB余分に)、それらのパフォーマンス(時間内)はまったく同じようです。

これで解決することを願っています!:)


-1

2つのバイナリの履歴やレガシーに関係なく、2つのバイナリの出力の違いを本当に知りたい場合は、いくつかのユーティリティを実行してこの違いを測定できます。debianでは、カスタム環境変数に応じて異なるいくつかのことを実行しました。

env |wc -l
printenv |wc -l

私の出力には両方とも41行があります

env > env.txt
printenv > printenv.txt
diff env.txt printenv.txt

出力:41c41 <_ = / usr / bin / env ---

_ = / usr / bin / printenv

そのため、2つに1つの行があり、その行は番号41であり、コマンドで使用されるバイナリを規定していると思います。追加の引数なしで、これらは私にとって事実上同一の情報を報告します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.