Jaký je rozdíl mezi dvěma příkazy env
a printenv
? Oba zobrazují proměnné prostředí a výstup je úplně stejný kromě _
.
Existují nějaké historické důvody, proč existují dva příkazy místo jednoho?
Přijatá odpověď:
Existují nějaké historické důvody, proč existují dva příkazy místo
jednoho?
Byl tam jen způsob historie.
- Bill Joy napsal první verzi
printenv
příkaz v roce 1979 pro BSD. - UNIX System III představil
env
velení v roce 1980. - GNU následovalo
env
UNIX System v roce 1986. - BSD následovalo
env
systému GNU/UNIX v roce 1988. - MINIX následoval
printenv
BSD v roce 1988. - GNU následovalo
printenv
MINX/BSD v roce 1989. - Včetně programovacích nástrojů GNU shellu 1.0
printenv
aenv
v roce 1991. - GNU Shell Utilities se v roce 2002 sloučily do GNU coreutils, což je to, co dnes najdete v GNU/Linuxu.
Všimněte si, že „sledováno“ neznamená, že zdrojový kód byl stejný, pravděpodobně byly přepsány, aby se předešlo soudním sporům o licence.
Takže důvod, proč oba příkazy existovaly, je ten, že Bill Joy napsal printenv
ještě před env
existoval.
Po 10 letech slučování/kompatibility a GNU na to narazilo, nyní vidíte oba podobné příkazy na stejné stránce.
Tato historie byla označena následovně: (Snažil jsem se minimalizovat odpověď a zde jsem uvedl pouze 2 základní úryvky zdrojového kódu. Zbytek si můžete zobrazit kliknutím na přiložené odkazy)
[podzim 1975]
Na podzim roku 1975 také dorazili dva nepovšimnutí postgraduální studenti, Bill Joy a Chuck Haley; oba se o nový systém okamžitě zajímali. Zpočátku začali pracovat na systému Pascal, který Thompson společně naboural, když se potloukal kolem strojovny 11/70.
[1977]
Joy začala kompilovat první Berkeley Software Distribution (1BSD), která byla vydána 9. března 1978. //rf:https://en.wikipedia.org/wiki/Berkeley_Software_Distribution
[únor, 1979]
1979(viz “Bill Joy, UCB únor, 1979”) /1980(viz “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]
Těžko určit, vydané v 2BSD NEBO 3BSD //rf:https://en.wikipedia.org/wiki/Berkeley_Software_Distribution
-
3BSD
Příkaz printenv se objevil ve 3.0 BSD. //rf:http://www.freebsd.org/cgi/man.cgi?query=printenv&sektion=1#end 3.0 BSD představen v roce 1979 //rf:http://gunkies.org/wiki/3_BSD -
2BSD
Příkaz printenv se poprvé objevil v 2BSD //rf:http://man.openbsd.org/printenv.1
[červen, 1980]
UNIX Release 3.0 NEBO „UNIX System III“ //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]
Související:Zásoba vs vývar – Jaký je rozdíl v použití?První printenv manuál BSD //rf:http://minnie.tuhs.org/cgi-bin/utree.pl?file=2.11BSD/src/man/man1/printenv.1
Nemohl jsem najít příručku týkající se env, ale nejbližší je getenv a environ //http://minnie.tuhs.org/cgi-bin/utree.pl?file=2.11BSD/src/man
[1986]
První verze 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 vydán //rf:https://en.wikipedia.org/wiki/Andrew_S._Tanenbaum
- Tanenbaum napsal klon UNIXu, nazvaný MINIX (MINi-unIX), pro IBM PC. Byl zaměřen na studenty a ostatní, kteří se chtěli naučit, jak operační systém funguje.
[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
[4. října 1988]
MINIX verze 1.3 //rf:https://groups.google.com/forum/#!topic/comp.os.minix/cQ8kaiq1hgI
…
32932 190 /minix/commands/printenv.c //printenv.c již existuje
//rf:http://www.informatica.co.cr/linux/research/1990/0202.htm
[1989]
První verze GNU printenv
viz [12. srpna 1993].
[16. července 1991]
„Shellutils“ – GNU shell programovací nástroje 1.0 vydané
//rf:https://groups.google.com/forum/#!topic/gnu.announce/xpTRtuFpNQc
Programy v tomto balíčku jsou:
basename datum dirname env expr groups id logname pathchk printenv printf sleep tee tty whoami ano pěkný nohup stty uname
[12. srpna 1993]
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, který nalezl zdrojový kód DSLinux v roce 2006 //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
[listopad 1993]
Byla vydána první verze FreeBSD. //rf:https://en.wikipedia.org/wiki/FreeBSD
[1. září 2002]
http://git.savannah.gnu.org/cgit/coreutils.git/tree/README-package-renamed-to-coreutils
Balíčky GNU fileutils, textutils a sh-utils (viz „Shellutils“ z 16. července 1991 výše) byly sloučeny do jednoho s názvem GNU coreutils.
Celkově env
případy použití porovnejte s printenv
:
-
tiskové proměnné prostředí, ale
printenv
může udělat totéž -
Zakázat vestavěný shell, ale lze toho dosáhnout pomocí
enable
cmd také. -
set variable, ale zbytečné, protože některé shelly to již umí bez
env
, např.$ HOME=/dev HOME=/tmp USER=root /bin/bash -c “cd ~; pwd”
/tmp
-
#!/usr/bin/env python
záhlaví, ale stále není přenosné, pokudenv
není v /usr/bin -
env -i
, zakázat všechna prostředí Považuji za užitečné zjistit kritické proměnné prostředí pro určitý program, aby se spouštěl zcrontab
. např. [1] V interaktivním režimu spusťtedeclare -p > /tmp/d.sh
k ukládání proměnných atributů. [2] V/tmp/test.sh
, napište:. /tmp/d.sh; eog /home/xiaobai/Pictures/1.jpg
[3] Nyní spusťteenv -i bash /tmp/test.sh
[4] Pokud se podaří zobrazit obrázek, odstraňte polovinu proměnných v/tmp/d.sh
a spusťteenv -i bash /tmp/test.sh
znovu. Pokud něco selhalo, vraťte to zpět. Opakujte krok pro zúžení. [5] Konečně jsem přišel na toeog
vyžaduje$DISPLAY
spustit vcrontab
a chybí$DBUS_SESSION_BUS_ADDRESS
zpomalí zobrazení obrázku. -
target_PATH="$PATH:$(sudo printenv PATH)";
je užitečné přímo použít kořenovou cestu, aniž byste museli dále analyzovat výstupenv
neboprintenv
.
např.:
[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]:~$