답변:
하나 대신 두 개의 명령이있는 역사적 이유가 있습니까?
역사 방식 만있었습니다.
printenv
1979 년 BSD를위한 첫 번째 버전의 명령을 작성했습니다 .env
은 1980 년에 명령을 도입 했습니다.env
는 1986 년 UNIX 시스템을 따랐습니다 .env
는 1988 년에 GNU / UNIX 시스템을 따랐습니다 .printenv
는 1988 년에 BSD를 따랐습니다 .printenv
는 1989 년에 MINX / BSD를 따랐습니다 .printenv
및 env
1천9백91인치"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
3BSD printenv 명령은 3.0 BSD에 나타났습니다. // rf : http://www.freebsd.org/cgi/man.cgi?query=printenv&sektion=1#end 3.0 BSD 1979 년 도입 // 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 첫 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
[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
다음 과 비교됩니다 .
printenv
동일한 작업을 수행 할 수 있습니다enable
cmd로도 달성 할 수 있습니다.이미하지 않고 그것을 할 수 있습니다 (때문에) 쉘에 변수하지만 무의미한 설정 env
, 예를 들어,
$ HOME = / dev HOME = / tmp USER = root / bin / bash -c "cd ~; pwd"
/ tmp
#!/usr/bin/env python
env
/ usr / bin에 있지 않은 경우 여전히 헤더가 아닌 휴대용
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
이미지가 표시되지 않으면
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:~$
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
다른 이진 / 스크립트 / 무엇을 호출하기 전에 일부 환경을 설정하는 것입니다.
이 방법이 더 명확합니까?
더 알고 :
man 1 env
(FreeBSD)man 1 printenv
(FreeBSD)env
명령은 4.4BSD에 나타났습니다. -P, -S 및 -v 옵션은 FreeBSD 6.0에서 추가되었습니다. 이 printenv
명령은 3.0BSD에 나타났습니다. 역사적인 이유 printenv
는 먼저 도착한 것 같습니다 .
맨 페이지에서 :
env-수정 된 환경에서 프로그램을 실행
...
printenv-환경의 전부 또는 일부를 인쇄
꽤 설명해야합니다.
printenv
는 현재 환경의 모든 변수를 인쇄합니다. 함께 env
당신은 필요한 경우 일부 수정과 같은 환경을 준비하고 그것에서 응용 프로그램을 실행할 수 있습니다.
ls
이진이지만 ll
일반적인 별칭이며 일반적으로로 확장됩니다 ls -l
. printenv
그리고 env
두 개의 다른 바이너리이며, 어느 것이 먼저 도입되었는지 잘 모르겠습니다. gnu.org/software/coreutils/manual/html_node/env-invocation.html
기능에 대해 엄격하게 이야기 env
하는 것은 환경 변수를 인쇄하는 반면 환경 변수를 인쇄하는 거대한 기능 세트를 가진 바이너리입니다 printenv
.
요약하면, env로 작업하는 데 익숙하다면 env
인쇄하는 데 사용됩니다 (이것이 익숙하기 때문에). 그렇지 않은 경우 일반적으로 printenv
더 빨리 기억 합니다.
환경 변수를 인쇄하는 것과 printenv
비교할 때 실제로 차이는 없습니다 env
. 방금 확인했는데 env가 약간 더 무겁고 (약 5KB 추가) 성능 (정시)은 정확히 같은 것으로 보입니다.
희망이 없어집니다! :)
히스토리와 레거시의 레거시에 관계없이 두 바이너리의 출력이 얼마나 다른지 알고 싶다면 몇 가지 유틸리티를 실행하여이 차이를 측정 할 수 있습니다. 데비안에서는 사용자 정의 환경 변수에 따라 다른 몇 가지 사항을 실행했습니다.
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 번이며 명령에 사용 된 이진을 지정합니다. 추가 인수가 없으면 이러한 정보가 거의 동일합니다.