GNU/Linux >> Linux の 問題 >  >> Linux

「env」と「printenv」の違いは?

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

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

承認された回答:

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

ただ歴史的なやり方がありました。

  1. BillJoyがprintenvの最初のバージョンを作成しました 1979年のBSD用コマンド。
  2. UNIXSystemIIIはenvを導入しました 1980年のコマンド。
  3. GNUはUNIXシステムのenvに従いました 1986年。
  4. BSDはGNU/UNIXシステムのenvに従いました 1988年。
  5. MINIXはBSDのprintenvに従いました 1988年。
  6. GNUはMINX/BSDのprintenvに従いました 1989年。
  7. GNUシェルプログラミングユーティリティ1.0にはprintenvが含まれています およびenv 1991年。
  8. GNU ShellUtilitiesは2002年にGNUcoreutilsに統合されました。これは、現在のGNU/Linuxに見られるものです。

「フォロー」は、ソースコードが同じであることを意味するものではなく、ライセンス訴訟を回避するために書き直された可能性があることに注意してください。

したがって、両方のコマンドが存在した理由は、BillJoyが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(「ビル・ジョイ、UCB 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.0BSDで登場しました。 // rf:http://www.freebsd.org/cgi/man.cgi?query=printenv&sektion=1#end 3.0BSDは1979年に導入されました//rf:http://gunkies.org/wiki/3_BSD

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

[1980年6月]

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

[[email protected] pdp11v3]$ sudo grep -rni printenv . //no such printenv exist.
[[email protected] 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
[[email protected] 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)
[[email protected] pdp11v3]$ 
[[email protected] 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);
}
[[email protected] pdp11v3]$

[1985]

関連:ストックvsブロス–使用法の違いは何ですか?

BSDの最初のprintenvマニュアル//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]

MINIX1stリリース//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


32932190/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」を参照)パッケージは、GNUcoreutilsと呼ばれる1つにマージされました。

全体として、env ユースケースはprintenvと比較します :

  1. 環境変数を出力しますが、printenv 同じことができます

  2. シェルビルトインを無効にしますが、enableで実現できます cmdも。

  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.shの変数の半分を削除します env -i bash /tmp/test.shを実行します また。何かが失敗した場合は、それを元に戻します。手順を繰り返して絞り込みます。 [5]最後にeogを見つけました $DISPLAYが必要です crontabで実行する 、および$DBUS_SESSION_BUS_ADDRESSがない 画像の表示が遅くなります。

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

例:

[email protected]:~$ sudo env | grep PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
[email protected]:~$ sudo printenv | grep PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
[email protected]:~$ sudo printenv PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
[email protected]:~$ sudo env PATH
env: ‘PATH’: No such file or directory
[email protected]:~$

Linux
  1. Sudo Su –とSudo Su —の違いは何ですか?

  2. GettyとAgettyの違いは?

  3. .exrcと.vimrcの違いは?

  1. ‘$の違い。 Foo」と「$./foo」??

  2. 〜/ .profileと〜/ .bash_profileの違いは?

  3. NssとPamの違いは?

  1. Cのstrtok_rとstrtok_sの違いは何ですか?

  2. adduser と useradd の違いは何ですか?

  3. $(CC) と $CC の違いは何ですか?