'Env' ve 'printenv' arasındaki fark nedir?


67

İki komutları arasındaki fark nedir envve printenv? Her ikisi de çevre değişkenlerini gösterir ve çıktı tam olarak aynıdır _.

Biri yerine iki emir olmasının tarihsel bir nedeni var mı?

Yanıtlar:


49

Biri yerine iki emir olmasının tarihsel bir nedeni var mı?

Sadece tarih tarzı vardı.

  1. Bill Joy printenv, 1979’da BSD’nin ilk emrini yazdı .
  2. UNIX System III env, 1980 yılında emri verdi.
  3. GNU env1986’da UNIX Sistemi’ni takip etti .
  4. BSD env1988'de GNU / UNIX Sistemini takip etti .
  5. MINIX printenv, 1988'de BSD'leri takip etti .
  6. GNU printenv1989'da MINX / BSD'leri takip etti .
  7. GNU kabuk programlama programları 1.0 dahil printenvve env1991'de.
  8. GNU Shell Utilities, 2002 yılında GNU coreutils ile birleşti; bu, bugünlerde GNU / Linux'ta kolayca bulabileceğiniz şeydi.

“İzlenen” in kaynak kodunun aynı olduğu anlamına gelmediğine dikkat edin, muhtemelen lisans davalarından kaçınmak için yeniden yazıldılar.

Öyleyse her iki komutun da var olmasının nedeni, Bill Joy'un printenvbu zamanı yazdığı zaman, envhenüz mevcut olmamasıdır. 10 yıllık birleşme / uyumluluk ve GNU ile karşılaştıktan sonra, aynı sayfada aynı komutları görüyorsunuz.

Bu tarih aşağıdaki gibi belirtildi: (Cevabı minimize etmeye çalışıyorum ve bu yüzden burada sadece 2 temel kaynak kodu veriyor, gerisini görmek için ekli bağlantıları tıklayabilirsiniz)

[1975 sonbaharında]

Ayrıca 1975 sonbaharında gelen farkedilmemiş iki yüksek lisans öğrencisi, Bill Joy ve Chuck Haley; Her ikisi de yeni sisteme derhal ilgi gösterdi. Başlangıçta, Thompson'ın 11/70 makina dairesinde dolanırken bir araya getirdiği bir Pascal sistemi üzerinde çalışmaya başladılar.

Ve diğerleri [1977]

Joy, 9 Mart 1978'de yayınlanan ilk Berkeley Yazılım Dağıtımını (1BSD) derlemeye başladı. // rf: https://en.wikipedia.org/wiki/Berkeley_Software_Distribution

[Şubat 1979]

1979 (bakınız "Bill Joy, UCB Şubat 1979") / 1980 (bkz. "Telif hakkı [] ="), printenv.c // rf: http://minnie.tuhs.org/cgi-bin/utree.pl? = 2.11BSD / src / ucb / printenv.c dosyası

/*
 * 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]

2BSD VEYA 3BSD'de yayımlanan belirlemek zor // rf: https://en.wikipedia.org/wiki/Berkeley_Software_Distribution

[Haziran 1980]

UNIX Sürüm 3.0 VEYA "UNIX Sistem III" // 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 ilk printenv kılavuzu // rf: http://minnie.tuhs.org/cgi-bin/utree.pl?file=2.11BSD/src/man/man1/printenv.1, ancak env ile ilgili kılavuzu bulamadım , en yakın getenv ve çevre // http://minnie.tuhs.org/cgi-bin/utree.pl?file=2.11BSD/src/man

[1986]

GNU’nun ilk sürümü env// rf: ftp://ftp-archive.freebsd.org/pub/FreeBSD-Archive/old-releases/i386/1.0-RELEASE/ports/shellutils/src/env.c

[1987]

MINIX 1. yayımlandı // rf: https://en.wikipedia.org/wiki/Andrew_S._Tanenbaum

  • Tanenbaum, IBM PC için MINIX (MINi-unIX) adlı bir UNIX klonu yazdı. Bir işletim sisteminin nasıl çalıştığını öğrenmek isteyen öğrencileri ve diğerlerini hedef aldı.

[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 Ekim 1988]

MINIX sürüm 1.3 // rf: https://groups.google.com/forum/#!topic/comp.os.minix/cQ8kaiq1hgI

... 32932 190 /minix/commands/printenv.c //printenv.c zaten var

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

[1989]

GNU’nun ilk versiyonu, printenv[12 Ağustos 1993].

[16 Temmuz 1991]

"Shellutils" - GNU kabuk programlama programları 1.0 yayımlandı // rf: https://groups.google.com/forum/#!topic/gnu.announce/xpTRtuFpNQc

Bu paketteki programlar:

basename tarih dirname env expr gruplar kimliği logname pathchk printenv printf uyku tee tty whoami evet güzel nohup stty uname

[12 Ağustos 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]

DSLinux kaynak kodunda 2006 yılında bulunan printenv.c // rf: (Google) önbellek: 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

[Kasım 1993]

FreeBSD'nin ilk sürümü yayınlandı. // rf: https://en.wikipedia.org/wiki/FreeBSD

[1 eylül 2002]

http://git.savannah.gnu.org/cgit/coreutils.git/tree/README-package-renamed-to-coreutils

GNU fileutils, textutils ve sh-utils (yukarıda 16 Temmuz 1991'de "Shellutils" konusuna bakın) paketleri GNU coreutils olarak adlandırılan bir birime birleştirildi.

Genel olarak, envkullanım durumları aşağıdakilerle karşılaştırılır printenv:

  1. ortam değişkenlerini yazdırabilir, ancak printenvaynısını yapabilir
  2. Kabuk yerleşikini devre dışı bırakın ancak enablecmd ile de başarabilirsiniz .
  3. Zaten olmadan bunu yapabilir nedeniyle bazı kabukları değişken ama anlamsız ayarlamak env, örneğin

    $ HOME = / dev HOME = / tmp KULLANICI = root / bin / bash -c "cd ~; pwd"

    / tmp

  4. #!/usr/bin/env pythonbaşlık, ancak env/ usr / bin içinde değilse, hala taşınabilir değil

  5. env -i, tüm env'yi devre dışı bırak. Belirli programın çalışmasını sağlamak için kritik ortam değişkenlerini bulmayı yararlı buldum crontab. örneğin [1] İnteraktif modda, declare -p > /tmp/d.shnitelik değişkenlerini saklamak için çalıştırın . [2] /tmp/test.shYazma: . /tmp/d.sh; eog /home/xiaobai/Pictures/1.jpg[3] Şimdi çalıştır env -i bash /tmp/test.sh[4] Görüntüyü göstermeyi başarırsa, değişkenlerin yarısını kaldırın /tmp/d.shve env -i bash /tmp/test.shtekrar çalıştırın . Bir şey başarısız olursa, geri al. Daraltmak için adımı tekrarlayın. [5] Sonunda, içeri eoggirmem $DISPLAYgerektiğini crontabve bunun olmamasının $DBUS_SESSION_BUS_ADDRESSgörüntünün görüntüsünü yavaşlatacağını anladım .

  6. target_PATH="$PATH:$(sudo printenv PATH)";envya da çıktısını daha fazla ayrıştırmaya gerek kalmadan doğrudan kök yolunu kullanmakta fayda var printenv.

Örneğin:

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

4
Güzel tarih dersi.
Ouki

21

Farklı bir bakış açısına sahip (FreeBSD'den),

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

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

Bu nedenle, bu komutlar argüman olmadan aynı etkiye sahip olabilir, ancak printenvtek amaç, geçerli ortam anahtarını / değerlerini göstermek, envhedef ise başka bir ikili / script / her neyi çağırmadan önce bazı ortamları belirlemektir.

Bu yol daha mı açık?

Daha fazla bilmek:


2
Verilen bağlantılarda Gönderen: komut 4.4BSD ortaya çıktı. -P, -S ve -v seçenekleri FreeBSD 6.0'da eklendi. Komut 3.0BSD ortaya çıktı. Öyleyse, tarihsel sebep ilk önce gelmiş görünüyor . env printenvprintenv
mcmlxxxvi


3

Man sayfalarından:

env - değiştirilmiş ortamda bir program çalıştır

...

printenv - ortamın tamamını veya bir kısmını yazdırın

Açıklayıcı olmalı.


4
ama alamadım ...
mikeserv

Galiba env, printenv'den önce geliyor. Peki neden başka bir ikili yapalım? 'İkili' olmadığından ve bir erkek sayfasına sahip olmadığından, bu '' 'ile' 'arasında olanla aynı değildir.
WiSaGaN

@mikeserv, printenvyalnızca geçerli ortamın tüm değişkenlerini yazdırır. Bununla envbirlikte, gerekirse bazı ortamlarda aynı ortamı hazırlayabilir ve içinde bir uygulama çalıştırabilirsiniz.
UVV

@WiSaGaN Karşılaştırma gerçekten doğru değil. lsİkili, ancak llgenellikle sadece genişleyen ortak bir takma addır ls -l. printenvve enviki farklı ikili, hangisinin ilk önce tanıtıldığından emin değilim. Burada daha fazla örnek görebilirsiniz gnu.org/software/coreutils/manual/html_node/env-invocation.html
UVV

1
@mikeserv, bu çizgi roman üzerindeki fare metnine bakınız . :)
Wildcard

3

Kesinlikle işlevsellikten bahsetmek env, bunlardan biri ortam değişkenlerini basmak olan çok büyük özelliklere sahip bir ikilidir, oysa printenvsadece ortam değişkenlerini yazdırır.

Özetle, eğer env ile çalışmaya alışkınsanız, envonları basmaya devam edersiniz (çünkü alışkın olduğunuz şeydir) ve eğer değilseniz, genellikle printenvdaha hızlı hatırlarsınız .

Bahsederken fark pratikte vardır printenvvs envsadece çevresel değişkenleri yazdırmak için. Sadece kontrol ettim ve env biraz daha ağır (yaklaşık 5 ekstra KB) ve performansları (zaman içinde) tamamen aynı görünüyor.

Umarım bu temizler! :)


-1

Tarihin ve bunların mirasına bakılmaksızın, iki çıkışın ne kadar farklı çıktılar olduğunu gerçekten bilmek istiyorsanız, bu farkı ölçmek için birkaç yardımcı program çalıştırabilirsiniz. Debian'da, herhangi bir özel çevre varyasyonuna bağlı olarak farklı olacak birkaç şey koştum:

env |wc -l
printenv |wc -l

Her iki çıktımda 41 satır var

env > env.txt
printenv > printenv.txt
diff env.txt printenv.txt

Çıktı: 41c41 <_ = / usr / bin / env ---

_ = / Usr / bin / printenv

Yani işte ikisinde farklı bir satır var ve bu satır da sayı 41'dir ve sanırım komutta kullanılan ikiliyi şart koşar. Ek argümanlar olmadan, bunlar benim için sanal özdeş bilgi rapor eder.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.