Saltar al contenido

¿Cuál es la diferencia entre ‘env’ y ‘printenv’?

Solución:

¿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 de printenv comando en 1979 para BSD.
  2. Se presenta UNIX System III env comando en 1980.
  3. GNU siguió el sistema UNIX env en 1986.
  4. BSD siguió el sistema GNU / UNIX env en 1988.
  5. MINIX siguió a BSD printenv en 1988.
  6. GNU siguió a MINX / BSD printenv en 1989.
  7. Utilidades de programación GNU Shell 1.0 incluidas printenv y env En 1991.
  8. GNU Shell Utilities se fusionó con GNU coreutils en 2002, que es lo que se encuentra en GNU / Linux hoy en día.

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 env existió. 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)

[fall of 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

[February, 1979]

1979 (ver “Bill Joy, UCB febrero de 1979”) / 1980 (ver “derechos de autor[] = “), 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("%sn", 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

[June, 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/

[[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: %sn", 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 environmentn");
                print();
                exit(1);
        }
        *p = arg;
        return;
}

print()
{
        register char **p = newenv;

        while (*p != NULL)
                printf("%sn", *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 == '' && *(s2-1) == '=')
                return(s2);
        return(NULL);
}
[[email protected] 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

[October 4, 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, Referirse a [August 12, 1993].

[July 16, 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:

nombre de base fecha dirname env ID de grupos expr nombre de registro pathchk printenv
printf dormir tee tty whoami sí bonito nohup stty uname

[August 12, 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

[November 1993]

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

[september 1, 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” en el 16 de julio de 1991 arriba) se han fusionado en uno, llamado GNU coreutils.

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

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

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

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

    $ INICIO = / dev INICIO = / tmp USUARIO = root / 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, escribir: . /tmp/d.sh; eog /home/xiaobai/Pictures/1.jpg [3] Ahora corre env -i bash /tmp/test.sh [4] Si tiene éxito para mostrar la imagen, elimine la mitad de las variables en /tmp/d.sh y correr env -i bash /tmp/test.sh de nuevo. Si algo falló, deshazlo. Repita el paso para reducir. [5] Finalmente me doy cuenta eog requiere $DISPLAY correr 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.

p.ej:

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

Teniendo un punto de vista diferente (de FreeBSD), tienes:

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.

Así que estos comandos pueden tener el mismo efecto sin argumentos, pero printenv El único propósito es mostrar la clave / valores del entorno actual mientras env objetivo establecer algún entorno antes de llamar a otro binario / script / lo que sea.

¿Está más claro así?

Para saber más:

  • man 1 env (FreeBSD)
  • man 1 printenv (FreeBSD)

env es POSIX 7, printenv no lo es (GNU Coreutils en Ubuntu 15.10).

¡Haz clic para puntuar esta entrada!
(Votos: 1 Promedio: 5)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *