GNU/Linux >> Linux Esercitazione >  >> Linux

La differenza tra "env" e "printenv"?

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.

  1. Bill Joy ha scritto la prima versione di printenv comando nel 1979 per BSD.
  2. UNIX System III ha introdotto env comando nel 1980.
  3. GNU ha seguito env di UNIX System nel 1986.
  4. BSD ha seguito env del sistema GNU/UNIX nel 1988.
  5. MINIX ha seguito printenv di BSD nel 1988.
  6. GNU ha seguito printenv di MINX/BSD nel 1989.
  7. Utility di programmazione della shell GNU 1.0 incluse printenv e env nel 1991.
  8. 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 :

  1. stampa le variabili d'ambiente, ma printenv può fare lo stesso

  2. Disabilita la shell incorporata ma puoi ottenere con enable anche cmd.

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

  4. #!/usr/bin/env python header, ma ancora non portabile se env non in /usr/bin

  5. env -i , disabilita tutti gli inv. Trovo utile capire le variabili di ambiente critiche per un determinato programma, per farlo funzionare da crontab . per esempio. [1] In modalità interattiva, esegui declare -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 esegui env -i bash /tmp/test.sh [4] Se la visualizzazione dell'immagine riesce, rimuovi metà delle variabili in /tmp/d.sh ed esegui env -i bash /tmp/test.sh ancora. Se qualcosa ha fallito, annullalo. Ripetere il passaggio per restringere il campo. [5] Finalmente ho scoperto eog richiede $DISPLAY da eseguire in crontab e assente di $DBUS_SESSION_BUS_ADDRESS rallenterà la visualizzazione dell'immagine.

  6. target_PATH="$PATH:$(sudo printenv PATH)"; è utile per utilizzare direttamente il percorso di root senza dover analizzare ulteriormente l'output di env o printenv .

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

Linux
  1. Qual è la differenza tra Sudo Su – e Sudo Su –?

  2. La differenza tra Getty e Agety?

  3. Differenza tra l'heap Java e l'heap C nativo

  4. Qual è la differenza tra fsck ed e2fsck?

  5. Qual è la differenza tra ls e l?

Qual è la differenza tra Linux e Unix?

Che cos'è un hypervisor? Qual è la differenza tra il tipo 1 e 2?

Qual è la differenza tra curl e Wget?

Qual è la differenza tra strtok_r e strtok_s in C?

Qual è la differenza tra adduser e useradd?

Qual è la differenza tra $(CC) e $CC?