GNU/Linux >> Tutoriales Linux >  >> Linux

¿La diferencia entre 'env' y 'printenv'?

¿Cuál es la diferencia entre los dos comandos env y printenv ? Ambos muestran las variables de entorno y el resultado es exactamente el mismo aparte de _ .

¿Hay alguna razón histórica para que haya dos comandos en lugar de uno?

Respuesta aceptada:

¿Hay alguna razón histórica para que haya dos comandos en lugar de
uno?

Lo había, solo a la manera de la historia.

  1. Bill Joy escribió la primera versión de printenv comando en 1979 para BSD.
  2. UNIX System III introdujo env mando en 1980.
  3. GNU siguió el env del sistema UNIX en 1986.
  4. BSD siguió el env del sistema GNU/UNIX en 1988.
  5. MINIX siguió el printenv de BSD en 1988.
  6. GNU siguió a printenv de MINX/BSD en 1989.
  7. Utilidades de programación de shell GNU 1.0 incluidas printenv y env en 1991.
  8. GNU Shell Utilities se fusionó con GNU coreutils en 2002, que es lo que encuentras en GNU/Linux hoy en día.

Tenga en cuenta que "seguido" no significa que el código fuente sea el mismo, probablemente se reescribieron para evitar demandas por licencias.

Entonces, la razón por la que existían ambos comandos es porque Bill Joy escribió printenv incluso antes de env existió.
Después de 10 años de fusión/compatibilidad y GNU lo encontró, ahora está viendo ambos comandos similares en la misma página.

Este historial se indica de la siguiente manera: (Traté de minimizar la respuesta y solo proporcioné 2 fragmentos de código fuente esenciales aquí. El resto puede hacer clic en los enlaces adjuntos para ver más)

[otoño de 1975]

También llegaron en el otoño de 1975 dos estudiantes graduados que pasaron desapercibidos, Bill Joy y Chuck Haley; ambos tomaron un interés inmediato en el nuevo sistema. Inicialmente, comenzaron a trabajar en un sistema Pascal que Thompson había pirateado mientras merodeaba por la sala de máquinas del 11/70.

[1977]

Joy comenzó a compilar la primera distribución de software de Berkeley (1BSD), que se lanzó el 9 de marzo de 1978. //rf:https://en.wikipedia.org/wiki/Berkeley_Software_Distribution

[febrero de 1979]

1979(ver “Bill Joy, UCB febrero de 1979”) /1980(ver “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]

Difícil de determinar publicado en 2BSD O 3BSD //rf:https://en.wikipedia.org/wiki/Berkeley_Software_Distribution

  • 3BSD
    El comando printenv apareció en 3.0 BSD. //rf:http://www.freebsd.org/cgi/man.cgi?query=printenv&sektion=1#end 3.0 BSD introducido en 1979 //rf:http://gunkies.org/wiki/3_BSD

  • 2BSD
    El comando printenv apareció por primera vez en 2BSD //rf:http://man.openbsd.org/printenv.1

[junio de 1980]

UNIX Versión 3.0 O “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]

Relacionado:Caldo vs caldo:¿cuál es la diferencia en el uso?

BSD primer manual printenv //rf:http://minnie.tuhs.org/cgi-bin/utree.pl?file=2.11BSD/src/man/man1/printenv.1

No pude encontrar el manual relacionado con env, pero el más cercano es getenv y environ //http://minnie.tuhs.org/cgi-bin/utree.pl?file=2.11BSD/src/man

[1986]

Primera versión 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 lanzamiento //rf:https://en.wikipedia.org/wiki/Andrew_S._Tanenbaum

  • Tanenbaum escribió un clon de UNIX, llamado MINIX (MINi-unIX), para IBM PC. Estaba dirigido a estudiantes y otras personas que querían aprender cómo funcionaba un sistema operativo.

[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 de octubre de 1988]

MINIX versión 1.3 //rf:https://groups.google.com/forum/#!topic/comp.os.minix/cQ8kaiq1hgI


32932 190 /minix/commands/printenv.c //printenv.c ya existe

//rf:http://www.informatica.co.cr/linux/research/1990/0202.htm

[1989]

La primera versión de GNU printenv , consulte [12 de agosto de 1993].

[16 de julio de 1991]

“Shellutils”:lanzamiento de las utilidades de programación de shell GNU 1.0
//rf:https://groups.google.com/forum/#!topic/gnu.announce/xpTRtuFpNQc

Los programas en este paquete son:

nombre base fecha dirname env expr grupos id logname pathchk printenv printf dormir tee tty whoami sí agradable nohup stty uname

[12 de agosto de 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 que se encontró en el código fuente 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

[noviembre de 1993]

Se lanzó la primera versión de FreeBSD. //rf:https://en.wikipedia.org/wiki/FreeBSD

[1 de septiembre de 2002]

http://git.savannah.gnu.org/cgit/coreutils.git/tree/README-package-renombrado-a-coreutils

Los paquetes GNU fileutils, textutils y sh-utils (ver "Shellutils" el 16 de julio de 1991 arriba) se fusionaron en uno, llamado GNU coreutils.

En general, env casos de uso comparar con printenv :

  1. imprimir variables de entorno, pero printenv puede hacer lo mismo

  2. Deshabilite el shell incorporado pero puede lograrlo con enable cmd también.

  3. establece una variable pero no tiene sentido debido a que algunos shells ya pueden hacerlo sin env , por ejemplo

    $ INICIO=/dev INICIO=/tmp USUARIO=raíz /bin/bash -c “cd ~; pwd”

    /tmp

  4. #!/usr/bin/env python encabezado, pero aún no es portátil si env no en /usr/bin

  5. env -i , deshabilite todos los env. Encuentro útil averiguar las variables de entorno críticas para cierto programa, para que se ejecute desde crontab . p.ej. [1] En modo interactivo, ejecute declare -p > /tmp/d.sh para almacenar variables de atributos. [2] En /tmp/test.sh , escriba:. /tmp/d.sh; eog /home/xiaobai/Pictures/1.jpg [3] Ahora ejecute env -i bash /tmp/test.sh [4] Si tiene éxito al mostrar la imagen, elimine la mitad de las variables en /tmp/d.sh y ejecuta env -i bash /tmp/test.sh otra vez. Si algo falla, deshazlo. Repita el paso para reducir. [5] Finalmente descubro eog requiere $DISPLAY para ejecutar en crontab , y ausente de $DBUS_SESSION_BUS_ADDRESS ralentizará la visualización de la imagen.

  6. target_PATH="$PATH:$(sudo printenv PATH)"; es útil para usar directamente la ruta raíz sin tener que analizar más la salida de env o printenv .

por ejemplo:

[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. ¿La diferencia entre [[ $a ==Z* ]] y [ $a ==Z* ]?

  2. La diferencia entre '$ . Foo' y '$ ./foo'??

  3. ¿La diferencia entre ~/.profile y ~/.bash_profile?

  4. ¿La diferencia entre Nss y Pam?

  5. ¿Cuál es la diferencia entre `su -` y `su --login`?

¿Cuál es la diferencia entre InnoDB y MyISAM?

¿Cuál es la diferencia entre Linux y Unix?

¿Qué es un Hipervisor? ¿Cuál es la diferencia entre el tipo 1 y 2?

¿Cuál es la diferencia entre curl y Wget?

¿Cuál es la diferencia entre ls y l?

¿Cuál es la diferencia entre $(CC) y $CC?