Was ist der Unterschied zwischen den beiden Befehlen env
und printenv
? Beide zeigen die Umgebungsvariablen und die Ausgabe ist bis auf _
genau gleich .
Gibt es historische Gründe dafür, dass es zwei Befehle anstelle von einem gibt?
Akzeptierte Antwort:
Gibt es historische Gründe dafür, dass es zwei Befehle
statt einem gibt?
Es gab nur eine historische Art.
- Bill Joy schrieb die erste Version von
printenv
Kommando 1979 für BSD. - UNIX System III hat
env
eingeführt Befehl im Jahr 1980. - GNU folgte dem
env
des UNIX-Systems 1986. - BSD folgte dem
env
des GNU/UNIX-Systems 1988. - MINIX folgte BSDs
printenv
1988. - GNU folgte MINX/BSDs
printenv
im Jahr 1989. - GNU Shell Programming Utilities 1.0 enthielt
printenv
undenv
1991. - GNU Shell Utilities verschmolzen 2002 mit GNU Coreutils, was Sie heute in GNU/Linux finden.
Beachten Sie, dass „gefolgt“ nicht bedeutet, dass der Quellcode derselbe war, wahrscheinlich wurden sie umgeschrieben, um Lizenzklagen zu vermeiden.
Der Grund, warum beide Befehle existierten, ist, dass Bill Joy printenv
geschrieben hat noch vor env
existierte.
Nach 10 Jahren der Zusammenführung/Kompatibilität und GNU stieß darauf, sehen Sie jetzt beide ähnlichen Befehle auf derselben Seite.
Dieser Verlauf wird wie folgt angezeigt: (Ich habe versucht, die Antwort zu minimieren und hier nur 2 wesentliche Quellcodeausschnitte bereitgestellt. Den Rest können Sie auf die beigefügten Links klicken, um mehr zu sehen)
[Herbst 1975]
Ebenfalls im Herbst 1975 trafen zwei unbemerkte Doktoranden ein, Bill Joy und Chuck Haley; Beide interessierten sich sofort für das neue System. Anfangs begannen sie mit der Arbeit an einem Pascal-System, das Thompson zusammengehackt hatte, während er im Maschinenraum von 11/70 herumhing.
[1977]
Joy begann mit der Kompilierung der ersten Berkeley Software Distribution (1BSD), die am 9. März 1978 veröffentlicht wurde. //rf:https://en.wikipedia.org/wiki/Berkeley_Software_Distribution
[Februar 1979]
1979 (siehe „Bill Joy, UCB Februar 1979“) /1980 (siehe „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]
Schwer zu bestimmen, veröffentlicht in 2BSD ODER 3BSD //rf:https://en.wikipedia.org/wiki/Berkeley_Software_Distribution
-
3BSD
Der printenv-Befehl erschien in 3.0 BSD. //rf:http://www.freebsd.org/cgi/man.cgi?query=printenv&sektion=1#end 3.0 BSD eingeführt 1979 //rf:http://gunkies.org/wiki/3_BSD -
2BSD
Der printenv-Befehl erschien zuerst in 2BSD //rf:http://man.openbsd.org/printenv.1
[Juni 1980]
UNIX Release 3.0 ODER „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]
Siehe auch:Brühe vs. Brühe – Was ist der Unterschied in der Verwendung?Erstes BSD-Printenv-Handbuch //rf:http://minnie.tuhs.org/cgi-bin/utree.pl?file=2.11BSD/src/man/man1/printenv.1
Ich konnte das Handbuch zu env nicht finden, aber das nächste ist getenv und environ //http://minnie.tuhs.org/cgi-bin/utree.pl?file=2.11BSD/src/man
[1986]
Erste Version von 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 veröffentlicht //rf:https://en.wikipedia.org/wiki/Andrew_S._Tanenbaum
- Tanenbaum schrieb einen Clone von UNIX namens MINIX (MINi-unIX) für den IBM PC. Es richtete sich an Studenten und andere, die lernen wollten, wie ein Betriebssystem funktioniert.
[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. Oktober 1988]
MINIX-Version 1.3 //rf:https://groups.google.com/forum/#!topic/comp.os.minix/cQ8kaiq1hgI
…
32932 190 /minix/commands/printenv.c //printenv.c existiert bereits
//rf:http://www.informatica.co.cr/linux/research/1990/0202.htm
[1989]
Die erste Version von GNU printenv
, siehe [12. August 1993].
[16. Juli 1991]
„Shellutils“ – GNU Shell Programming Utilities 1.0 veröffentlicht
//rf:https://groups.google.com/forum/#!topic/gnu.announce/xpTRtuFpNQc
Die Programme in diesem Paket sind:
Basisname Datum Verzeichnisname env expr Gruppen-ID Protokollname Pfadchk printenv printf sleep tee tty whoami yes nice nohup stty uname
[12. August 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, das 2006 auf DSLinux-Quellcode gefunden wurde //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
[November 1993]
Die erste Version von FreeBSD wurde veröffentlicht. //rf:https://en.wikipedia.org/wiki/FreeBSD
[1. September 2002]
http://git.savannah.gnu.org/cgit/coreutils.git/tree/README-package-renamed-to-coreutils
Die GNU-Pakete fileutils, textutils und sh-utils (siehe „Shellutils“ vom 16. Juli 1991 oben) wurden zu einem Paket namens GNU coreutils zusammengeführt.
Insgesamt, env
Anwendungsfälle vergleichen mit printenv
:
-
Umgebungsvariablen drucken, aber
printenv
kann dasselbe tun -
Deaktiviert die eingebaute Shell, kann aber mit
enable
erreicht werden cmd auch. -
Variable setzen, aber sinnlos, da einige Shells dies bereits ohne
env
tun können , z. B.$ HOME=/dev HOME=/tmp USER=root /bin/bash -c „cd ~; pwd“
/tmp
-
#!/usr/bin/env python
Header, aber immer noch nicht portierbar, wennenv
nicht in /usr/bin -
env -i
, alle env deaktivieren. Ich finde es nützlich, die kritischen Umgebungsvariablen für ein bestimmtes Programm herauszufinden, damit es voncrontab
ausgeführt wird . z.B. [1] Führen Sie im interaktiven Modusdeclare -p > /tmp/d.sh
aus um Attributvariablen zu speichern. [2] In/tmp/test.sh
, schreibe:. /tmp/d.sh; eog /home/xiaobai/Pictures/1.jpg
[3] Führen Sie nunenv -i bash /tmp/test.sh
aus [4] Wenn das Bild erfolgreich angezeigt wird, entfernen Sie die Hälfte der Variablen in/tmp/d.sh
und führen Sieenv -i bash /tmp/test.sh
aus wieder. Wenn etwas fehlgeschlagen ist, machen Sie es rückgängig. Wiederholen Sie den Schritt zum Eingrenzen. [5] Endlich finde icheog
heraus erfordert$DISPLAY
incrontab
auszuführen , und ohne$DBUS_SESSION_BUS_ADDRESS
verlangsamt die Bildanzeige. -
target_PATH="$PATH:$(sudo printenv PATH)";
ist nützlich, um den Root-Pfad direkt zu verwenden, ohne die Ausgabe vonenv
weiter analysieren zu müssen oderprintenv
.
zB:
[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]:~$