Yanıtlar:
Biri yerine iki emir olmasının tarihsel bir nedeni var mı?
Sadece tarih tarzı vardı.
printenv
, 1979’da BSD’nin ilk emrini yazdı .env
, 1980 yılında emri verdi.env
1986’da UNIX Sistemi’ni takip etti .env
1988'de GNU / UNIX Sistemini takip etti .printenv
, 1988'de BSD'leri takip etti .printenv
1989'da MINX / BSD'leri takip etti .printenv
ve env
1991'de.“İ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 printenv
bu zamanı yazdığı zaman, env
henü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
3BSD printenv komutu 3.0 BSD'de göründü. // rf: http://www.freebsd.org/cgi/man.cgi?query=printenv&sektion=1#end 1979'da tanıtılan 3.0 BSD // rf: http://gunkies.org/wiki/3_BSD
2BSD printenv komutu ilk önce 2BSD // rf: http://man.openbsd.org/printenv.1
[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
[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, env
kullanım durumları aşağıdakilerle karşılaştırılır printenv
:
printenv
aynısını yapabilirenable
cmd ile de başarabilirsiniz .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
#!/usr/bin/env python
başlık, ancak env
/ usr / bin içinde değilse, hala taşınabilir değil
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.sh
nitelik değişkenlerini saklamak için çalıştırın . [2] /tmp/test.sh
Yazma: . /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.sh
ve env -i bash /tmp/test.sh
tekrar çalıştırın . Bir şey başarısız olursa, geri al. Daraltmak için adımı tekrarlayın. [5] Sonunda, içeri eog
girmem $DISPLAY
gerektiğini crontab
ve bunun olmamasının $DBUS_SESSION_BUS_ADDRESS
görüntünün görüntüsünü yavaşlatacağını anladım .
target_PATH="$PATH:$(sudo printenv PATH)";
env
ya 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:~$
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 printenv
tek amaç, geçerli ortam anahtarını / değerlerini göstermek, env
hedef ise başka bir ikili / script / her neyi çağırmadan önce bazı ortamları belirlemektir.
Bu yol daha mı açık?
Daha fazla bilmek:
man 1 env
(FreeBSD)man 1 printenv
(FreeBSD)env
printenv
printenv
env
POSIX 7'dir ,printenv
değildir (Ubuntu 15.10'daki GNU Coreutils).
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ı.
printenv
yalnızca geçerli ortamın tüm değişkenlerini yazdırır. Bununla env
birlikte, gerekirse bazı ortamlarda aynı ortamı hazırlayabilir ve içinde bir uygulama çalıştırabilirsiniz.
ls
İkili, ancak ll
genellikle sadece genişleyen ortak bir takma addır ls -l
. printenv
ve env
iki 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
Kesinlikle işlevsellikten bahsetmek env
, bunlardan biri ortam değişkenlerini basmak olan çok büyük özelliklere sahip bir ikilidir, oysa printenv
sadece ortam değişkenlerini yazdırır.
Özetle, eğer env ile çalışmaya alışkınsanız, env
onları basmaya devam edersiniz (çünkü alışkın olduğunuz şeydir) ve eğer değilseniz, genellikle printenv
daha hızlı hatırlarsınız .
Bahsederken fark pratikte vardır printenv
vs env
sadece ç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! :)
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.