Quelle est la différence entre les deux commandes env
et printenv
? Ils affichent tous les deux les variables d'environnement, et la sortie est exactement la même à part _
.
Existe-t-il des raisons historiques pour qu'il y ait deux commandes au lieu d'une ?
Réponse acceptée :
Existe-t-il des raisons historiques pour qu'il y ait deux commandes au lieu d'une ?
Il y avait, juste de la manière historique.
- Bill Joy a écrit la première version de
printenv
commande en 1979 pour BSD. - UNIX System III a introduit
env
commande en 1980. - GNU a suivi
env
du système UNIX en 1986. - BSD a suivi
env
du système GNU/UNIX en 1988. - MINIX a suivi le
printenv
de BSD en 1988. - GNU a suivi le
printenv
de MINX/BSD en 1989. - Utilitaires de programmation du shell GNU 1.0 inclus
printenv
etenv
en 1991. - GNU Shell Utilities a fusionné avec GNU coreutils en 2002, ce que l'on trouve actuellement dans GNU/Linux.
Notez que le "suivi" ne signifie pas que le code source était le même, ils ont probablement été réécrits pour éviter les poursuites en matière de licence.
Donc, la raison pour laquelle les deux commandes existaient est que Bill Joy a écrit printenv
avant même env
existé.
Après 10 ans de fusion/compatibilité et GNU l'a découvert, vous voyez maintenant les deux commandes similaires sur la même page.
Cet historique indique comme suit : (J'ai essayé de minimiser la réponse et je n'ai fourni que 2 extraits de code source essentiels ici. Pour le reste, vous pouvez cliquer sur les liens ci-joints pour en savoir plus)
[automne 1975]
Arrivent également à l'automne 1975 deux étudiants diplômés inaperçus, Bill Joy et Chuck Haley; tous deux s'intéressèrent immédiatement au nouveau système. Au départ, ils ont commencé à travailler sur un système Pascal que Thompson avait piraté ensemble alors qu'il traînait dans la salle des machines 11/70.
[1977]
Joy a commencé à compiler la première Berkeley Software Distribution (1BSD), qui a été publiée le 9 mars 1978. //rf :https://en.wikipedia.org/wiki/Berkeley_Software_Distribution
[février 1979]
1979(voir "Bill Joy, UCB février 1979") /1980(voir "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]
Difficile à déterminer sorti en 2BSD OU 3BSD //rf :https://en.wikipedia.org/wiki/Berkeley_Software_Distribution
-
3BSD
La commande printenv est apparue dans 3.0 BSD. //rf :http://www.freebsd.org/cgi/man.cgi?query=printenv&sektion=1#end 3.0 BSD introduit en 1979 //rf :http://gunkies.org/wiki/3_BSD -
2BSD
La commande printenv est apparue pour la première fois dans 2BSD //rf :http://man.openbsd.org/printenv.1
[juin 1980]
UNIX version 3.0 OU « 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]
En relation:Stock vs Broth - Quelle est la différence d'utilisation?Premier manuel d'impression BSD //rf :http://minnie.tuhs.org/cgi-bin/utree.pl?file=2.11BSD/src/man/man1/printenv.1
Je n'ai pas trouvé le manuel lié à env, mais le plus proche est getenv et environ //http://minnie.tuhs.org/cgi-bin/utree.pl?file=2.11BSD/src/man
[1986]
Première version de GNU env
//rf :ftp://ftp-archive.freebsd.org/pub/FreeBSD-Archive/old-releases/i386/1.0-RELEASE/ports/shellutils/src/env.c
[1987]
MINIX 1er publié //rf :https://en.wikipedia.org/wiki/Andrew_S._Tanenbaum
- Tanenbaum a écrit un clone d'UNIX, appelé MINIX (MINi-unIX), pour l'IBM PC. Il s'adressait aux étudiants et aux autres personnes souhaitant découvrir le fonctionnement d'un système d'exploitation.
[1988]
BSD 1er 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 octobre 1988]
MINIX version 1.3 //rf :https://groups.google.com/forum/#!topic/comp.os.minix/cQ8kaiq1hgI
…
32932 190 /minix/commands/printenv.c //printenv.c existe déjà
//rf :http://www.informatica.co.cr/linux/research/1990/0202.htm
[1989]
La première version de GNU printenv
, se référer au [12 août 1993].
[16 juillet 1991]
« Shellutils » – Publication des utilitaires de programmation shell GNU 1.0
//rf :https://groups.google.com/forum/#!topic/gnu.announce/xpTRtuFpNQc
Les programmes de ce package sont :
nom de base date dirname env expr groupes id logname pathchk printenv printf sleep tee tty whoami oui sympa nohup stty uname
[12 août 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 trouvé sur le code source de DSLinux en 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
[Novembre 1993]
La première version de FreeBSD est sortie. //rf :https://en.wikipedia.org/wiki/FreeBSD
[1er septembre 2002]
http://git.savannah.gnu.org/cgit/coreutils.git/tree/README-package-renamed-to-coreutils
Les packages GNU fileutils, textutils et sh-utils (voir "Shellutils" au 16 juillet 1991 ci-dessus) ont été fusionnés en un seul, appelé GNU coreutils.
Globalement, env
cas d'utilisation comparer avec printenv
:
-
imprimer les variables d'environnement, mais
printenv
peut faire la même chose -
Désactiver le shell intégré mais peut y parvenir avec
enable
cmd aussi. -
set variable mais inutile car certains shells peuvent déjà le faire sans
env
, par exemple$ HOME=/dev HOME=/tmp USER=root /bin/bash -c "cd ~; pwd"
/tmp
-
#!/usr/bin/env python
en-tête, mais toujours pas portable sienv
pas dans /usr/bin -
env -i
, désactiver tous les env. Je trouve utile de comprendre les variables d'environnement critiques pour certains programmes, pour le faire fonctionner à partir decrontab
. par exemple. [1] En mode interactif, exécutezdeclare -p > /tmp/d.sh
pour stocker les variables d'attributs. [2] Dans/tmp/test.sh
, écrivez :. /tmp/d.sh; eog /home/xiaobai/Pictures/1.jpg
[3] Exécutez maintenantenv -i bash /tmp/test.sh
[4] Si l'affichage de l'image réussit, supprimez la moitié des variables dans/tmp/d.sh
et exécutezenv -i bash /tmp/test.sh
de nouveau. Si quelque chose a échoué, annulez-le. Répétez l'étape pour affiner. [5] Enfin j'ai compriseog
nécessite$DISPLAY
à exécuter danscrontab
, et absent de$DBUS_SESSION_BUS_ADDRESS
ralentira l'affichage de l'image. -
target_PATH="$PATH:$(sudo printenv PATH)";
est utile pour utiliser directement le chemin racine sans avoir à analyser davantage la sortie deenv
ouprintenv
.
ex :
[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]:~$