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

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

env두 명령의 차이점은 무엇입니까 printenv? 둘 다 환경 변수를 표시하며 그 점을 제외하면 출력은 동일합니다 _.

하나가 아닌 두 개의 명령을 사용하는 역사적 이유가 있습니까?

답변1

하나가 아닌 두 개의 명령을 사용하는 역사적 이유가 있습니까?

역사가 그러합니다.

역사

  1. printenvBill Joy는 1979년에 BSD 명령의 첫 번째 버전을 작성했습니다.
  2. UNIX System III env에서는 1980년에 명령을 도입했습니다.
  3. GNU는 UNIX 시스템에 이어 1986년에 등장했습니다 env.
  4. BSD는 GNU/UNIX 시스템에 이어 1988년에 등장했습니다 env.
  5. MINIX는 1988년에 BSD의 뒤를 따랐습니다 printenv.
  6. GNU는 1989년에 MINX/BSD의 뒤를 따랐습니다 printenv.
  7. 1991 printenvGNU 쉘 프로그래밍 유틸리티 1.0이 포함되어 있습니다.env
  8. GNU Shell Utilities는 2002년에 GNU coreutils로 병합되었으며 이것이 오늘날 GNU/Linux에서 볼 수 있는 것입니다.

"follow"는 소스 코드가 동일하다는 의미는 아니며 라이센스 소송을 피하기 위해 다시 작성되었을 수도 있습니다.

따라서 이 두 명령은 Bill Joy가 존재하기 printenv전에 작성했기 때문에 존재합니다 env. 10년 동안의 병합/호환성과 GNU를 만난 후 이제 같은 페이지에서 두 개의 유사한 명령을 볼 수 있습니다.

이 기록은 다음을 보여줍니다. (답변을 최소한으로 유지하려고 노력했으며 여기에는 두 개의 기본 소스 코드 조각만 제공했습니다. 나머지는 첨부된 링크를 클릭하여 자세히 볼 수 있습니다.)

[1975년 가을]

1975년 가을, 눈에 띄지 않는 두 명의 대학원생인 빌 조이(Bill Joy)와 척 헤일리(Chuck Haley)도 도착했습니다. 그들은 모두 새로운 제도에 즉각적인 관심을 보였습니다. 처음에 그들은 Thompson이 11월 70일에 컴퓨터실에서 놀면서 함께 해독한 Pascal 시스템 작업을 시작했습니다.

[1977]

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

[1979년 2월]

1979("Bill Joy, UCB February, 1979" 참조)/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

[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 첫 번째 릴리스 //rf:https://en.wikipedia.org/wiki/Andrew_S._Tanenbaum

  • Tanenbaum은 IBM PC용 MINIX(MINI-unIX)라는 UNIX 복제품을 작성했습니다. 운영 체제의 작동 방식을 이해하려는 학생 및 기타 사용자를 대상으로 합니다.

[1988]

BSD 첫 번째 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

이 패키지에 포함된 프로그램은 다음과 같습니다.

기본 이름 날짜 디렉터리 이름환경expr 그룹 ID 로그 이름 경로 chk인쇄환경 printf sleep Tee tty whoami 네, 좋아요 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 쉘 유틸리티 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) 캐시: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, 모든 환경을 비활성화합니다. 속성 변수를 저장하기 위해 crontab. 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:~$
    

답변2

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목표는 다른 바이너리/스크립트/무엇이든 호출하기 전에 일부 환경을 설정하는 것입니다.

이것이 더 명확해지지 않습니까?

더 알고 싶으세요?

답변3

env POSIX 7입니다,printenv 아니요(Ubuntu 15.10의 GNU Coreutils).

답변4

엄밀히 말하면 env수많은 기능을 갖춘 바이너리이며 그 중 하나는 환경 변수를 인쇄하고 printenv환경 변수만 인쇄하는 것입니다.

전체적으로, env 사용에 익숙하다면 계속 env인쇄하게 될 것입니다(왜냐하면 이것이 익숙하기 때문입니다). 그렇지 않다면 일반적으로 printenv더 빨리 기억할 것입니다.

printenv환경 변수 에 대해 이야기하는 것과 그냥 인쇄하는 것 사이에는 env실제로 차이가 없습니다 . 방금 확인했는데 env가 약간 더 무겁고(약 5KB 더 높음) 성능(시간상)은 정확히 동일한 것 같습니다.

이것이 문제를 해결하기를 바랍니다! :)

관련 정보