'env'와 'printenv'의 차이점은 무엇입니까?


67

두 명령 env과 의 차이점은 무엇입니까 printenv? 둘 다 환경 변수를 표시하며 출력은에서와 정확히 동일 _합니다.

하나 대신 두 개의 명령이있는 역사적 이유가 있습니까?

답변:


49

하나 대신 두 개의 명령이있는 역사적 이유가 있습니까?

역사 방식 만있었습니다.

  1. Bill Joy는 printenv1979 년 BSD를위한 첫 번째 버전의 명령을 작성했습니다 .
  2. UNIX System III env은 1980 년에 명령을 도입 했습니다.
  3. GNU env는 1986 년 UNIX 시스템을 따랐습니다 .
  4. BSD env는 1988 년에 GNU / UNIX 시스템을 따랐습니다 .
  5. MINIX printenv는 1988 년에 BSD를 따랐습니다 .
  6. GNU printenv는 1989 년에 MINX / BSD를 따랐습니다 .
  7. GNU 쉘 프로그래밍 유틸리티 포함 1.0 printenvenv1천9백91인치
  8. GNU Shell Utilities는 2002 년에 GNU coreutils에 통합되었으며, 오늘날 GNU / Linux에서 쉽게 찾을 수있었습니다.

"followed"는 소스 코드가 동일 함을 의미하지 않으며 라이센스 소송을 피하기 위해 다시 작성된 것 같습니다.

따라서 두 명령이 존재하는 이유는 Bill Joy가 printenv그 시간을 쓸 때 env아직 존재하지 않기 때문입니다. 10 년 동안의 병합 / 호환성 및 GNU가 나오면 이제 같은 페이지에 비슷한 명령이 모두 표시됩니다.

로 표시이 역사는 다음과 같습니다 (I 답을 최소화하려고 그렇게 만, 여기 링크보고 연결을 클릭 할 수있는 나머지 2 필수 소스 코드를 제공)

[1975 년 가을]

1975 년 가을에 빌 조이 (Bill Joy)와 척 헤일리 (Chuck Haley) 두 명의 주목받지 못한 대학원생들이 도착했다. 그들은 새로운 시스템에 즉각적인 관심을 보였습니다. 처음에 그들은 톰슨이 11/70 기계실 주위에 매달려있는 동안 해킹 한 파스칼 시스템 작업을 시작했습니다.

[1977]

Joy는 1978 년 3 월 9 일에 릴리스 된 최초의 Berkeley Software Distribution (1BSD)을 컴파일하기 시작했습니다. // rf : https://en.wikipedia.org/wiki/Berkeley_Software_Distribution

[1979 년 2 월]

1979 ( "BCB Bill Joy, 1979 년 2 월"참조) / 1980 ( "copyright [] ="참조), printenv.c // rf : http://minnie.tuhs.org/cgi-bin/utree.pl? 파일 = 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

[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 첫 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]

MINIX 1st // rf : https://ko.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

이 패키지의 프로그램은 다음과 같습니다.

기본 이름 날짜 dirname env expr groups id logname pathchk printenv printf sleep tee tty whoami 예 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]

printenv.c (2006 년 DSLinux 소스 코드에서 찾을 수 있음) // 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 pythonenv/ usr / bin에 있지 않은 경우 여전히 헤더가 아닌 휴대용

  5. env -i, 모든 env를 비활성화하십시오. 특정 프로그램이 실행되도록하는 중요한 환경 변수를 알아내는 것이 유용하다는 것을 알았습니다 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.

예 :

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
제공된 링크에서 : env명령은 4.4BSD에 나타났습니다. -P, -S 및 -v 옵션은 FreeBSD 6.0에서 추가되었습니다. printenv명령은 3.0BSD에 나타났습니다. 역사적인 이유 printenv는 먼저 도착한 것 같습니다 .
mcmlxxxvi


3

맨 페이지에서 :

env-수정 된 환경에서 프로그램을 실행

...

printenv-환경의 전부 또는 일부를 인쇄

꽤 설명해야합니다.


4
그러나 나는 그것을 얻지 못한다 ...
mikeserv

env가 printenv보다 먼저 온다고 가정합니다. 그렇다면 왜 다른 바이너리를 만드나요? 'll'은 바이너리가 아니고 매뉴얼 페이지가 없기 때문에 'll'에서 'ls'의 내용과 동일하지 않습니다.
WiSaGaN

@mikeserv printenv는 현재 환경의 모든 변수를 인쇄합니다. 함께 env당신은 필요한 경우 일부 수정과 같은 환경을 준비하고 그것에서 응용 프로그램을 실행할 수 있습니다.
UVV

@WiSaGaN 귀하의 비교는 실제로 정확하지 않습니다. ls이진이지만 ll일반적인 별칭이며 일반적으로로 확장됩니다 ls -l. printenv그리고 env두 개의 다른 바이너리이며, 어느 것이 먼저 도입되었는지 잘 모르겠습니다. gnu.org/software/coreutils/manual/html_node/env-invocation.html
UVV

1
@ mikeserv, 이 만화 의 마우스 오버 텍스트를 참조하십시오 . :)
와일드 카드

3

기능에 대해 엄격하게 이야기 env하는 것은 환경 변수를 인쇄하는 반면 환경 변수를 인쇄하는 거대한 기능 세트를 가진 바이너리입니다 printenv.

요약하면, env로 작업하는 데 익숙하다면 env인쇄하는 데 사용됩니다 (이것이 익숙하기 때문에). 그렇지 않은 경우 일반적으로 printenv더 빨리 기억 합니다.

환경 변수를 인쇄하는 것과 printenv비교할 때 실제로 차이는 없습니다 env. 방금 확인했는데 env가 약간 더 무겁고 (약 5KB 추가) 성능 (정시)은 정확히 같은 것으로 보입니다.

희망이 없어집니다! :)


-1

히스토리와 레거시의 레거시에 관계없이 두 바이너리의 출력이 얼마나 다른지 알고 싶다면 몇 가지 유틸리티를 실행하여이 차이를 측정 할 수 있습니다. 데비안에서는 사용자 정의 환경 변수에 따라 다른 몇 가지 사항을 실행했습니다.

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

그래서 두 줄에 한 줄이 다르고 그 줄은 41 번이며 명령에 사용 된 이진을 지정합니다. 추가 인수가 없으면 이러한 정보가 거의 동일합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.