GNU/Linux >> Tutoriels Linux >  >> Linux

La différence entre "env" et "printenv" ?

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.

  1. Bill Joy a écrit la première version de printenv commande en 1979 pour BSD.
  2. UNIX System III a introduit env commande en 1980.
  3. GNU a suivi env du système UNIX en 1986.
  4. BSD a suivi env du système GNU/UNIX en 1988.
  5. MINIX a suivi le printenv de BSD en 1988.
  6. GNU a suivi le printenv de MINX/BSD en 1989.
  7. Utilitaires de programmation du shell GNU 1.0 inclus printenv et env en 1991.
  8. 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 :

  1. imprimer les variables d'environnement, mais printenv peut faire la même chose

  2. Désactiver le shell intégré mais peut y parvenir avec enable cmd aussi.

  3. 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

  4. #!/usr/bin/env python en-tête, mais toujours pas portable si env pas dans /usr/bin

  5. 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 de crontab . par exemple. [1] En mode interactif, exécutez declare -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 maintenant env -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écutez env -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 compris eog nécessite $DISPLAY à exécuter dans crontab , et absent de $DBUS_SESSION_BUS_ADDRESS ralentira l'affichage de l'image.

  6. target_PATH="$PATH:$(sudo printenv PATH)"; est utile pour utiliser directement le chemin racine sans avoir à analyser davantage la sortie de env ou printenv .

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]:~$

Linux
  1. Quelle est la différence entre InnoDB et MyISAM ?

  2. Quelle est la différence entre Sudo Su - et Sudo Su - ?

  3. La différence entre .exrc et .vimrc ?

  4. La différence entre '$ . Foo' Et '$ ./foo' ? ?

  5. La différence entre ~/.profile et ~/.bash_profile ?

Quelle est la différence entre Linux et Unix ?

Qu'est-ce qu'un Hyperviseur ? Quelle est la différence entre les types 1 et 2 ?

Quelle est la différence entre curl et Wget ?

Quelle est la différence entre adduser et useradd ?

Quelle est la différence entre `su -` et `su --login` ?

Quelle est la différence entre unlink et rm ?