'Env' और 'printenv' में क्या अंतर है?


67

दो आदेशों के बीच क्या अंतर है envऔर printenv? वे दोनों पर्यावरण चर दिखाते हैं, और आउटपुट बिल्कुल उसी तरफ से है _

वहाँ एक के बजाय दो आदेश होने के लिए कोई ऐतिहासिक कारण हैं?

जवाबों:


49

वहाँ एक के बजाय दो आदेश होने के लिए कोई ऐतिहासिक कारण हैं?

सिर्फ इतिहास का तरीका था।

  1. बिल जॉय ने printenvबीएसडी के लिए 1979 में कमांड का पहला संस्करण लिखा ।
  2. UNIX सिस्टम III ने env1980 में कमांड की शुरुआत की ।
  3. GNU ने env1986 में UNIX System का अनुसरण किया ।
  4. BSD ने env1988 में GNU / UNIX सिस्टम का अनुसरण किया ।
  5. printenv1988 में MINIX ने BSD का अनुसरण किया ।
  6. GNU ने printenv1989 में MINX / BSD का अनुसरण किया ।
  7. GNU शेल प्रोग्रामिंग उपयोगिताओं 1.0 में शामिल printenvऔर env1991 में।
  8. GNU शेल यूटिलिटीज 2002 में GNU कोरुटिल्स में विलीन हो गई, जो कि आप आजकल GNU / Linux में आसानी से पा सकते थे।

ध्यान दें कि "फ़ॉलो किया गया" का अर्थ स्रोत कोड समान नहीं था, शायद वे लाइसेंस मुकदमे से बचने के लिए फिर से लिखे गए थे।

इसलिए दोनों आज्ञाओं का अस्तित्व क्यों है क्योंकि जब बिल जॉय ने printenvउस समय लिखा था, तब envतक अस्तित्व में नहीं है। विलय / अनुकूलता और GNU के 10 साल पूरे होने के बाद, अब आप एक ही पृष्ठ पर दोनों समान कमांड देख रहे हैं।

यह इतिहास निम्नानुसार है: (मैं उत्तर को कम से कम करने की कोशिश करता हूं और इसलिए यहां केवल 2 आवश्यक स्रोत कोड प्रदान करता हूं, बाकी आप देखने के लिए संलग्न लिंक पर क्लिक कर सकते हैं)

[1975 का पतन]

1975 के पतन में पहुंचने वाले दो अविभाजित स्नातक छात्र बिल जॉय और चक हेली थे; उन दोनों ने नई प्रणाली में तत्काल रुचि ली। शुरू में उन्होंने पास्कल सिस्टम पर काम करना शुरू किया, जिसे थॉम्पसन ने 11/70 मशीन के कमरे में लटकाते हुए एक साथ हैक कर लिया था।

[1977]

जॉय ने पहली बर्कले सॉफ्टवेयर डिस्ट्रीब्यूशन (1BSD) की रचना शुरू की, जो 9 मार्च, 1978 को जारी की गई। // rf: https://en.wikipedia.org/wiki/Berkeley_Software_Distribution

[फरवरी, 1979]

1979 (देखें "बिल जॉय, यूसीबी फरवरी, 1979") / 1980 ("कॉपीराइट [] =" देखें), printenv.c // rf: http://minnie.tuhs.org/cgi-bin/utree.pl फ़ाइल = 2.11BSD / src / यूसीबी / 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]

2BSD या 3BSD // rf में जारी किया गया निर्धारित करने के लिए कठिन: https://en.wikipedia.org/wiki/Berkeley_Software_Distribution

[जून, 1980]

UNIX रिलीज़ 3.0 या "UNIX सिस्टम 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 पहले प्रिंटेनव मैनुअल // rf: http://minnie.tuhs.org/cgi-bin/utree.pl?file=2.11BSD/src/man/man1/printenv.1 लेकिन मैं मैनुअल से संबंधित नहीं मिल सकता , निकटतम है getenv और environ // http://minnie.tuhs.org/cgi-bin/utree.pl?file=2.11BSD/src/man

[1986]

GNU env// rf का पहला संस्करण : ftp://ftp-archive.freebsd.org/pub/FreeBSD-Archive/old-releases/i386/1.0-RELEASE/ports/srutils/src/env.c

[1987]

न्यूनतम 1 जारी // rf: https://en.wikipedia.org/wiki/Andrew_S._Tanenbaum

  • Tanenbaum ने UNIX का एक क्लोन लिखा, जिसे MINIX (MINi-unIX) कहा जाता है, IBM PC के लिए। यह उन छात्रों और अन्य लोगों पर लक्षित था जो सीखना चाहते थे कि एक ऑपरेटिंग सिस्टम कैसे काम करता है।

[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 अक्टूबर, 1988]

MINIX संस्करण 1.3 // rf: https://groups.google.com/forum/# .topic/comp.os.minix/cQ8kaiq1hgI

... 32932 190 /minix/commands/printenv.c //printenv.c पहले से मौजूद है

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

[1989]

जीएनयू का पहला संस्करण printenv, [12 अगस्त, 1993] को देखें।

[१६ जुलाई १ ९९ १]

"शेल्यूटिल्स" - जीएनयू शेल प्रोग्रामिंग यूटिलिटीज 1.0 जारी // rf: https://groups.google.com/forum//topic/gnu.announce/xpTRtuFpNQc

इस पैकेज के कार्यक्रम इस प्रकार हैं:

basename date dirname env expr group id logname pathchk printenv प्रिंटफ स्लीप टी टी ट्टी जोमी हां नाइस नूप स्ट्टी अनमी

[12 अगस्त, 1993]

Printenv.c // rf: ftp://ftp-archive.freebsd.org/pub/FreeBSD-Archive/old-releases/i386/1.0-RELEASE/ports/shellbils/src/printenv.c

, GNU शेल उपयोगिताएँ 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 जो 2006 में DSLinux स्रोत कोड पर पाया गया // rf: (Google) कैश: mailman.dslinux.in-berlin.de/pipermail/dslinux-commit-dslinux.in-berlin.de/2006-August/000578। एचटीएमएल

--- NEW FILE: printenv.c ---
/*
 * Copyright (c) 1993 by David I. Bell

[नवंबर 1993]

फ्रीबीएसडी का पहला संस्करण जारी किया गया था। // rf: https://en.wikipedia.org/wiki/FreeBSD

[सितम्बर १, २००२]

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

GNU फाइलुटिल्स, टेक्स्टुटिल्स, और श-बर्तनों (16 जुलाई, 1991 को "शेलुटिल्स देखें") संकुल को एक में विलय कर दिया गया है, जिसे GNU कोरुटिल्स कहा जाता है।

कुल मिलाकर, envमामलों की तुलना करें printenv:

  1. पर्यावरण चर प्रिंट, लेकिन printenvएक ही कर सकते हैं
  2. शेल निर्मित अक्षम करें लेकिन enablecmd के साथ भी प्राप्त कर सकते हैं।
  3. परिवर्तनशील लेकिन कुछ बिंदुओं के कारण व्यर्थ सेट पहले से ही इसके बिना कर सकते हैं env, जैसे

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

    / tmp

  4. #!/usr/bin/env pythonहेडर, लेकिन फिर भी पोर्टेबल envनहीं है अगर / usr / बिन में नहीं

  5. env -i, सभी env को निष्क्रिय करें। मैंने पाया कि इसे चलाने के लिए कुछ प्रोग्राम के लिए महत्वपूर्ण पर्यावरण चर का पता लगाना उपयोगी था crontab। उदाहरण के लिए [१] इंटरेक्टिव मोड में, declare -p > /tmp/d.shस्टोरेज वैरिएबल को चलाएं । [२] इसमें /tmp/test.sh, लिखें: . /tmp/d.sh; eog /home/xiaobai/Pictures/1.jpg[३] अब चलाएं env -i bash /tmp/test.sh[४] अगर यह छवि प्रदर्शित करने में सफल होता है, तो आधे चरों को हटा दें /tmp/d.shऔर env -i bash /tmp/test.shफिर से चलाएं । यदि कुछ विफल हुआ, तो उसे पूर्ववत करें। संकीर्ण करने के लिए चरण दोहराएँ। [५] अंत में मुझे पता है कि eogइसमें $DISPLAYभाग लेने की आवश्यकता है crontab, और अनुपस्थित $DBUS_SESSION_BUS_ADDRESSछवि का प्रदर्शन धीमा कर देगा।

  6. target_PATH="$PATH:$(sudo printenv PATH)";बिना रूट के पार्सिंग को आगे बढ़ाने के लिए सीधे रूट पथ का उपयोग करने के लिए उपयोगी है envया printenv

उदाहरण के लिए:

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
अच्छा इतिहास पाठ।
ओउकी

21

एक अलग दृष्टिकोण (FreeBSD से) होने के बाद, आपके पास:

से 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.

से 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.

तो इन आदेशों का तर्क के बिना एक ही प्रभाव हो सकता है, लेकिन printenvएकमात्र उद्देश्य वर्तमान पर्यावरण कुंजी / मूल्यों को प्रदर्शित करना है जबकि envलक्ष्य यह है कि किसी अन्य बाइनरी / स्क्रिप्ट / जो भी कॉल करने से पहले कुछ वातावरण सेट करें।

क्या यह इस तरह से अधिक स्पष्ट है?

अधिक जाना जाता है:


2
दिए गए लिंक से: आदेश 4.4BSD में दिखाई दिया। FreeBSD 6.0 में -P, -S और -v विकल्प जोड़े गए। आदेश 3.0BSD में दिखाई दिया। तो ऐतिहासिक कारण यह लगता है कि पहले पहुंचे। env printenvprintenv
mcmlxxxvi


3

मानव-पृष्ठों से:

env - एक प्रोग्राम को संशोधित वातावरण में चलाएं

...

Printenv - पर्यावरण के सभी या भाग को प्रिंट करें

सुंदर व्याख्यात्मक होना चाहिए।


4
लेकिन मुझे यह नहीं मिला ...
mikeserv

मुझे लगता है कि Printvv से पहले env आता है। तो एक और बाइनरी क्यों बनाएं? यह 'll' के साथ 'ls' के समान नहीं है क्योंकि 'll' कोई बाइनरी नहीं है और इसमें मैन पेज नहीं है।
WiSaGaN

@mikeserv printenvसिर्फ वर्तमान परिवेश के सभी चर प्रिंट करता है। साथ envआप यदि आवश्यक हो तो कुछ संशोधनों के साथ ही वातावरण तैयार करने और उस में कोई एप्लिकेशन चला सकते हैं।
यूवीवी

@WiSaGaN आपकी तुलना वास्तव में सही नहीं है। lsएक द्विआधारी है, लेकिन llएक सामान्य उपनाम है, जो आमतौर पर बस फैलता है ls -lprintenvऔर envदो अलग-अलग बायनेरिज़ हैं, मुझे यकीन नहीं है कि कौन सा पहली बार पेश किया गया था। आप यहाँ कुछ और उदाहरण देख सकते हैं gnu.org/software/coreutils/manual/html_node/env-invocation.html
UVV

1
@mikeserv, इस कॉमिक पर माउसओवर टेक्स्ट देखें । :)
वाइल्डकार्ड

3

कार्यात्मकताओं के बारे में कड़ाई से बात करते हुए, envएक द्विआधारी है जिसमें सुविधाओं का एक बड़ा समूह है, उनमें से एक मुद्रण पर्यावरण चर हैं, जबकि printenvसिर्फ प्रिंट चर।

संक्षेप में, यदि आपको env के साथ काम करने के लिए उपयोग किया जाता है, तो आप envउन्हें प्रिंट करने के लिए जाएंगे (क्योंकि यही आप उपयोग करते हैं) और यदि आप नहीं हैं, तो आप आमतौर पर printenvतेजी से याद करेंगे ।

केवल पर्यावरणीय चर मुद्रण के लिए printenvबनाम envके बारे में बात करते समय व्यावहारिक रूप से कोई मतभेद नहीं हैं । मैंने अभी जाँच की है और env थोड़ा भारी है (लगभग 5 अतिरिक्त KB), और उनका प्रदर्शन (समय में) बिल्कुल समान है।

आशा है कि यह इसे साफ करता है! :)


-1

यदि आप वास्तव में जानना चाहते हैं कि इतिहास और विरासत की परवाह किए बिना दोनों बायनेरिज़ के विभिन्न आउटपुट कितने हैं, तो आप इस अंतर को समझने के लिए कुछ उपयोगिताओं को चला सकते हैं। डेबियन पर मैंने कुछ चीजें चलाईं जो किसी भी कस्टम पर्यावरण संस्करण के आधार पर भिन्न होंगी:

env |wc -l
printenv |wc -l

मेरे दोनों आउटपुट में 41 लाइनें हैं

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

आउटपुट: 41c41 <_ = / usr / bin / env ---

_ = / Usr / bin / printenv

तो आप देखते हैं कि दोनों में एक लाइन अलग है और यह लाइन 41 नंबर की है, जो मुझे लगता है कि कमांड में इस्तेमाल किए गए बाइनरी को निर्धारित करता है। अतिरिक्त तर्कों के बिना, ये रिपोर्ट मेरे लिए आभासी समान जानकारी की रिपोर्ट करती है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.