Qual è la differenza tra i due comandi env
e printenv
? Entrambi mostrano le variabili di ambiente e l'output è esattamente lo stesso a parte _
.
Ci sono ragioni storiche per cui ci sono due comandi invece di uno?
Risposta accettata:
Ci sono ragioni storiche per cui ci sono due comandi invece
di uno?
C'era, solo maniera storica.
- Bill Joy ha scritto la prima versione di
printenv
comando nel 1979 per BSD. - UNIX System III ha introdotto
env
comando nel 1980. - GNU ha seguito
env
di UNIX System nel 1986. - BSD ha seguito
env
del sistema GNU/UNIX nel 1988. - MINIX ha seguito
printenv
di BSD nel 1988. - GNU ha seguito
printenv
di MINX/BSD nel 1989. - Utility di programmazione della shell GNU 1.0 incluse
printenv
eenv
nel 1991. - GNU Shell Utilities si è fusa in GNU coreutils nel 2002, che è ciò che trovi oggi in GNU/Linux.
Nota che il "seguito" non significa che il codice sorgente fosse lo stesso, probabilmente sono stati riscritti per evitare cause legali.
Quindi, il motivo per cui esistevano entrambi i comandi è perché Bill Joy ha scritto printenv
anche prima di env
esisteva.
Dopo 10 anni di fusione/compatibilità e GNU si è imbattuto in esso, ora vedi entrambi i comandi simili sulla stessa pagina.
Questa cronologia è indicata come segue: (Ho cercato di ridurre al minimo la risposta e ho fornito solo 2 frammenti di codice sorgente essenziali qui. Il resto puoi fare clic sui link allegati per vedere di più)
[autunno 1975]
Nell'autunno del 1975 arrivarono anche due studenti laureati inosservati, Bill Joy e Chuck Haley; entrambi si interessarono immediatamente al nuovo sistema. Inizialmente, hanno iniziato a lavorare su un sistema Pascal che Thompson aveva hackerato insieme mentre si aggirava nella sala macchine dell'11/70.
[1977]
Joy iniziò a compilare la prima Berkeley Software Distribution (1BSD), che fu rilasciata il 9 marzo 1978. //rf:https://en.wikipedia.org/wiki/Berkeley_Software_Distribution
[febbraio 1979]
1979(vedi “Bill Joy, UCB febbraio 1979”) /1980(vedi “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 da determinare rilasciato in 2BSD O 3BSD //rf:https://en.wikipedia.org/wiki/Berkeley_Software_Distribution
-
3BSD
Il comando printenv è apparso in 3.0 BSD. //rf:http://www.freebsd.org/cgi/man.cgi?query=printenv&sektion=1#end 3.0 BSD introdotto nel 1979 //rf:http://gunkies.org/wiki/3_BSD -
2BSD
Il comando printenv è apparso per la prima volta in 2BSD //rf:http://man.openbsd.org/printenv.1
[giugno 1980]
UNIX versione 3.0 OPPURE “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]
Correlati:Stock vs Brodo:qual è la differenza nell'utilizzo?Manuale BSD first printenv //rf:http://minnie.tuhs.org/cgi-bin/utree.pl?file=2.11BSD/src/man/man1/printenv.1
Non sono riuscito a trovare il manuale relativo a env, ma il più vicino è getenv e environ //http://minnie.tuhs.org/cgi-bin/utree.pl?file=2.11BSD/src/man
[1986]
Prima versione di GNU env
//rf:ftp://ftp-archive.freebsd.org/pub/FreeBSD-Archive/old-releases/i386/1.0-RELEASE/ports/shellutils/src/env.c
[1987]
MINIX 1° rilasciato //rf:https://en.wikipedia.org/wiki/Andrew_S._Tanenbaum
- Tanenbaum ha scritto un clone di UNIX, chiamato MINIX (MINI-unIX), per il PC IBM. Era rivolto a studenti e altri che volevano imparare come funzionava un sistema operativo.
[1988]
BSD 1° 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 ottobre 1988]
MINIX versione 1.3 //rf:https://groups.google.com/forum/#!topic/comp.os.minix/cQ8kaiq1hgI
…
32932 190 /minix/commands/printenv.c //printenv.c esiste già
//rf:http://www.informatica.co.cr/linux/research/1990/0202.htm
[1989]
La prima versione di GNU printenv
, fare riferimento a [12 agosto 1993].
[16 luglio 1991]
"Shellutils" – Utilità di programmazione shell GNU 1.0 rilasciate
//rf:https://groups.google.com/forum/#!topic/gnu.announce/xpTRtuFpNQc
I programmi in questo pacchetto sono:
basename data dirname env espr gruppi id nome registro percorso printenv printf sleep tee tty whoami yes nice nohup stty uname
[12 agosto 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 trovato nel codice sorgente di DSLinux nel 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]
È stata rilasciata la prima versione di FreeBSD. //rf:https://en.wikipedia.org/wiki/FreeBSD
[1 settembre 2002]
http://git.savannah.gnu.org/cgit/coreutils.git/tree/README-package-rinomed-to-coreutils
I pacchetti GNU fileutils, textutils e sh-utils (vedi “Shellutils” al 16 luglio 1991 sopra) sono stati fusi in uno, chiamato GNU coreutils.
In generale, env
i casi d'uso confrontano con printenv
:
-
stampa le variabili d'ambiente, ma
printenv
può fare lo stesso -
Disabilita la shell incorporata ma puoi ottenere con
enable
anche cmd. -
set variabile ma inutile perché alcune shell possono già farlo senza
env
, ad es.$ HOME=/dev HOME=/tmp USER=root /bin/bash -c “cd ~; pwd”
/tmp
-
#!/usr/bin/env python
header, ma ancora non portabile seenv
non in /usr/bin -
env -i
, disabilita tutti gli inv. Trovo utile capire le variabili di ambiente critiche per un determinato programma, per farlo funzionare dacrontab
. per esempio. [1] In modalità interattiva, eseguideclare -p > /tmp/d.sh
per memorizzare le variabili degli attributi. [2] In/tmp/test.sh
, scrivi:. /tmp/d.sh; eog /home/xiaobai/Pictures/1.jpg
[3] Ora eseguienv -i bash /tmp/test.sh
[4] Se la visualizzazione dell'immagine riesce, rimuovi metà delle variabili in/tmp/d.sh
ed eseguienv -i bash /tmp/test.sh
ancora. Se qualcosa ha fallito, annullalo. Ripetere il passaggio per restringere il campo. [5] Finalmente ho scopertoeog
richiede$DISPLAY
da eseguire incrontab
e assente di$DBUS_SESSION_BUS_ADDRESS
rallenterà la visualizzazione dell'immagine. -
target_PATH="$PATH:$(sudo printenv PATH)";
è utile per utilizzare direttamente il percorso di root senza dover analizzare ulteriormente l'output dienv
oprintenv
.
es:
[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]:~$