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 _
.
Y a-t-il des raisons historiques pour lesquelles il y a deux commandes au lieu d'une?
Y a-t-il des raisons historiques pour lesquelles il y a deux commandes au lieu d'une?
Il y avait juste une histoire.
printenv
en 1979 pour BSD.env
en 1980.env
d'UNIX System en 1986.env
du système GNU/UNIX en 1988.printenv
de BSD en 1988.printenv
de MINX/BSD en 1989.printenv
et env
en 1991.Notez que le "suivi" ne signifie pas que le code source était le même, probablement ils ont été réécrits pour éviter un procès de licence.
Donc, la raison pour laquelle les deux commandes existaient est parce que lorsque Bill Joy a écrit printenv
à ce moment-là, le env
n'existe pas encore. Après 10 ans de fusion/compatibilité et GNU rencontré, vous voyez maintenant les deux commandes similaires sur la même page.
Cet historique est indiqué comme suit: (J'essaie de minimiser la réponse et ne fournit donc que 2 codes sources essentiels ici, le reste, vous pouvez cliquer liens attachés pour voir)
[automne 1975]
Arrivant également à l'automne 1975, deux étudiants diplômés inaperçus, Bill Joy et Chuck Haley; ils se sont tous deux intéressés immédiatement au nouveau système. Au début, ils ont commencé à travailler sur un système Pascal que Thompson avait piraté ensemble en traînant dans la salle des machines 11/70.
[1977]
Joy a commencé à compiler la première distribution de logiciel Berkeley (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 publié dans 2BSD OR 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 OR "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 premier manuel printenv // rf: http://minnie.tuhs.org/cgi-bin/utree.pl?file=2.11BSD/src/man/man1/printenv.1 mais je peux 'ai pas trouvé de manuel lié à env, 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 1st sorti // rf: https://en.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
[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]
Première version de GNU printenv
, voir [12 août 1993].
[16 juillet 1991]
"Shellutils" - GNU Utilitaires de programmation Shell 1.0 publiés // rf: https://groups.google.com/forum/#!topic/gnu.announce/xpTRtuFpNQc =
Les programmes de ce package sont:
nom de base date dirname env expr groups id logname pathchk printenv printf sleep tee tty whoami oui Nice 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 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 se comparent à printenv
:
printenv
peut faire de mêmeenable
cmd.définir une 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
En-tête #!/usr/bin/env python
, Mais toujours pas portable si env
pas dans/usr/bin
env -i
, Désactivez tout env. J'ai trouvé utile de comprendre les variables d'environnement critiques de certains programmes pour les faire fonctionner à partir de crontab
. par exemple. [1] En mode interactif, exécutez declare -p > /tmp/d.sh
Pour stocker les variables d'attribut. [2] Dans /tmp/test.sh
, Écrivez: . /tmp/d.sh; eog /home/xiaobai/Pictures/1.jpg
[3] Maintenant, exécutez env -i bash /tmp/test.sh
[4] S'il réussit à afficher l'image, supprimez la moitié des variables dans /tmp/d.sh
et exécutez à nouveau env -i bash /tmp/test.sh
. Si quelque chose a échoué, annulez-le. Répétez l'étape pour réduire. [5] Enfin, je pense que eog
nécessite que $DISPLAY
S'exécute dans crontab
et que l'absence 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 de env
ou printenv
.
par exemple:
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:~$
Ayant un point de vue différent (de FreeBSD), vous avez:
De 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.
De 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.
Donc, ces commandes peuvent avoir le même effet sans argument, mais printenv
le seul but est d'afficher la clé/les valeurs d'environnement actuelles tandis que env
le but de définir un environnement avant d'appeler un autre binaire/script/peu importe .
Est-ce plus clair de cette façon?
Pour en savoir plus:
man 1 env
(FreeBSD)man 1 printenv
(FreeBSD)env
est POSIX 7, printenv
n'est pas (GNU Coreutils dans Ubuntu 15.10).
Depuis les pages de manuel:
env - exécuter un programme dans un environnement modifié
...
printenv - imprime tout ou partie de l'environnement
Devrait être assez explicatif.
Parlant strictement de fonctionnalités, env
est un binaire avec un ensemble énorme de fonctionnalités, l'une d'entre elles étant l'impression de variables d'environnement, tandis que printenv
imprime simplement des variables d'environnement.
En résumé, si vous avez l'habitude de travailler avec env, vous irez avec env
pour les imprimer (car c'est ce à quoi vous êtes habitué) et si vous ne l'êtes pas, vous vous souviendrez généralement printenv
plus rapidement .
Il n'y a pratiquement aucune différence lorsque l'on parle de printenv
vs env
pour l'impression de variables d'environnement uniquement. Je viens de vérifier et env est légèrement plus lourd (environ 5 Ko supplémentaires), et leurs performances (dans le temps) semblent être exactement les mêmes.
J'espère que cela le clarifie! :)