environment-variables – ¿Cuál es la diferencia entre 'env' y 'printenv'?

Pregunta:

¿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 _ .

¿Existen razones históricas para que haya dos comandos en lugar de uno?

Respuesta:

¿Existen razones históricas para que haya dos comandos en lugar de uno?

Había, simplemente estilo histórico.

  1. Bill Joy escribió la primera versión del comando printenv en 1979 para BSD.
  2. UNIX System III introdujo el comando env en 1980.
  3. GNU siguió al env del sistema UNIX en 1986.
  4. BSD siguió al env del sistema GNU / UNIX en 1988.
  5. MINIX siguió el printenv de BSD en 1988.
  6. GNU seguido de MINX / BSD printenv en 1989.
  7. Las utilidades de programación de shell GNU 1.0 incluyeron printenv y env en 1991.
  8. GNU Shell Utilities se fusionó con GNU coreutils en 2002, que es lo que se encuentra actualmente en GNU / Linux.

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

Entonces, la razón por la que existieron ambos comandos es porque Bill Joy escribió printenv incluso antes de que existiera env . Después de 10 años de fusión / compatibilidad y GNU lo encuentra, 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 inadvertidos, Bill Joy y Chuck Haley; ambos se interesaron de inmediato en el nuevo sistema. Inicialmente, comenzaron a trabajar en un sistema Pascal que Thompson había pirateado mientras merodeaban por la sala de máquinas 11/70.

[1977]

Joy comenzó a compilar la primera distribución de software de Berkeley (1BSD), que se publicó 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? archivo = 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

[Junio ​​de 1980]

Versión 3.0 de UNIX O "Sistema III de UNIX" // 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 first printenv manual // 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 environment //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 lanzado // 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 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 de octubre de 1988]

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

… 32932190 /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 de GNU 1.0 // rf: https://groups.google.com/forum/#!topic/gnu.announce/xpTRtuFpNQc

Los programas de este paquete son:

basename date dirname env expr grupos id logname pathchk printenv printf sleep tee tty whoami yes nice 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-renamed-to-coreutils

Los paquetes GNU fileutils, textutils y sh-utils (ver "Shellutils" del 16 de julio de 1991 más arriba) se han fusionado en uno, llamado GNU coreutils.

En general, los casos de uso de env se comparan con printenv :

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

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

  3. establecer variable pero inútil debido a que algunos shells ya pueden hacerlo sin env , por ejemplo

    $ INICIO = / dev INICIO = / tmp USUARIO = root / bin / bash -c "cd ~; pwd"

    / tmp

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

  5. env -i , deshabilita todos los env. Encuentro útil averiguar las variables de entorno críticas para cierto programa, para que se ejecute desde crontab . Por ejemplo, [1] En modo interactivo, ejecute declare -p > /tmp/d.sh para almacenar variables de atributos. [2] En /tmp/test.sh , escribir: . /tmp/d.sh; eog /home/xiaobai/Pictures/1.jpg [3] Ahora ejecute env -i bash /tmp/test.sh [4] Si muestra la imagen /tmp/d.sh , elimine la mitad de las variables en /tmp/d.sh y ejecute env -i bash /tmp/test.sh nuevo. Si algo falló, deshazlo. Repita el paso para reducir. [5] Finalmente me doy cuenta de que eog requiere $DISPLAY para ejecutarse en crontab , y la ausencia de $DBUS_SESSION_BUS_ADDRESS ralentizará la visualización de la imagen.

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

p.ej:

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

Leave a Comment

Your email address will not be published. Required fields are marked *

web tasarım