回答:
1つではなく2つのコマンドがあるという歴史的な理由はありますか?
ただ歴史的なマナーがありました。
printenv
1979年にBSD用のコマンドの最初のバージョンを書きました。env
は1980年にコマンドを導入しました。env
は1986年にUNIXシステムに続きました。env
1988年、BSDはGNU / UNIXシステムに準拠しました。printenv
1988年にMINIXはBSDに準拠しました。printenv
は1989年にMINX / BSDに続きました。printenv
とenv
1991インチ「フォロー」はソースコードが同じであることを意味しないことに注意してください。おそらくライセンス訴訟を避けるためにソースコードが書き直されました。
両方のコマンドが存在した理由は、ビル・ジョイがprintenv
その時間を書いたとき、env
まだ存在していないためです。10年のマージ/互換性とGNUがそれに遭遇した後、同じページに両方の同様のコマンドが表示されています。
この履歴は次のように示されています:( 答えを最小化しようとしているため、ここでは2つの必須ソースコードのみを提供し、残りは添付のリンクをクリックして表示します)
[1975年の秋]
1975年の秋には、2人の見知らぬ大学院生、ビルジョイとチャックヘイリーも到着しました。彼らは両方とも新しいシステムにすぐに興味を持ちました。当初、彼らはトンプソンが11/70の機械室をぶらぶらしているときに一緒にハッキングしたPascalシステムの開発を始めました。
[1977]
Joyは、1978年3月9日にリリースされた最初のBerkeley Software Distribution(1BSD)のコンパイルを開始しました。// rf:https : //en.wikipedia.org/wiki/Berkeley_Software_Distribution
[1979年2月]
1979(「ビルジョイ、1979年2月」を参照)/ 1980(「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]
2BSDまたは3BSD // rfでリリースされたと判断するのは難しい:https : //en.wikipedia.org/wiki/Berkeley_Software_Distribution
3BSD printenvコマンドは3.0 BSDで登場しました。// rf:http ://www.freebsd.org/cgi/man.cgi ? query = printenv&sektion=1#end 3.0 1979年に導入されたBSD // rf:http : //gunkies.org/wiki/3_BSD
2BSD printenvコマンドは2BSD // rfで初めて登場しました:http ://man.openbsd.org/printenv.1
[1980年6月]
UNIXリリース3.0または「UNIX System 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 first printenv manual // rf:http ://minnie.tuhs.org/cgi-bin/utree.pl?file=2.11BSD/src/man/man1/printenv.1 しかし、envに関連するマニュアルが見つかりません、最も近いのは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/shellutils/src/env.c
[1987]
MINIX 1stリリース// rf:https : //en.wikipedia.org/wiki/Andrew_S._Tanenbaum
[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
[1988年10月4日]
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]
GNUの最初のバージョンはprintenv
、[1993年8月12日]を参照してください。
[1991年7月16日]
「Shellutils」-GNUシェルプログラミングユーティリティ1.0リリース// rf:https ://groups.google.com/forum/#!topic/gnu.announce/xpTRtuFpNQc
このパッケージのプログラムは次のとおりです。
basename date dirname env expr groups id logname pathchk printenv printf sleep tee tty whoami yes nice nohup stty uname
[1993年8月12日]
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]
2006年のDSLinuxソースコードで見つかったprintenv.c // 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
[1993年11月]
FreeBSDの最初のバージョンがリリースされました。// rf:https : //en.wikipedia.org/wiki/FreeBSD
[2002年9月1日]
http://git.savannah.gnu.org/cgit/coreutils.git/tree/README-package-renamed-to-coreutils
GNU fileutils、textutils、sh-utils(上記の1991年7月16日の「Shellutils」を参照)パッケージは、GNU coreutilsと呼ばれるものにマージされました。
全体的に、env
ユースケースは次と比較されprintenv
ます:
printenv
、同じことができますenable
cmdでも実現できます。変数を設定しますが、いくつかのシェルがなくてもそれを行うことができるため、無意味ですenv
、例えば
$ HOME = / dev HOME = / tmp USER = root / bin / bash -c "cd〜; pwd"
/ tmp
#!/usr/bin/env python
ヘッダーですがenv
、/ usr / binにない場合は移植できません
env -i
、すべての環境を無効にします。特定のプログラムを実行するための特定のプログラムの重要な環境変数を把握しておくと便利ですcrontab
。例[1]インタラクティブモードでは、実行declare -p > /tmp/d.sh
して属性変数を保存します。[2]で/tmp/test.sh
、書き込み:. /tmp/d.sh;
eog /home/xiaobai/Pictures/1.jpg
[3]今すぐ実行env -i bash /tmp/test.sh
[4]イメージの表示に成功したら、変数の半分を削除して/tmp/d.sh
、env -i bash /tmp/test.sh
もう一度実行します。何かが失敗した場合は、元に戻します。手順を繰り返して絞り込みます。[5]最後に、で実行するeog
必要があることがわかります。これがないと、画像の表示が遅くなります。$DISPLAY
crontab
$DBUS_SESSION_BUS_ADDRESS
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:~$
(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
ことです。
この方法はより明確ですか?
もっと知るには:
man 1 env
(FreeBSD)man 1 printenv
(FreeBSD)env
printenv
printenv
env
はPOSIX 7ですが、そうでprintenv
はありません(Ubuntu 15.10のGNU Coreutils)。
マンページから:
env-変更された環境でプログラムを実行する
...
printenv-環境の全部または一部を出力します
かなり説明的なはずです。
printenv
は、現在の環境のすべての変数を出力するだけです。ではenv
、あなたは必要に応じていくつかの変更と同じ環境を用意し、その中にアプリを実行することができます。
ls
はバイナリll
ですが、一般的なエイリアスであり、通常は単にに展開されls -l
ます。2つの異なるバイナリがprintenv
ありenv
ますが、どちらが最初に導入されたかはわかりません。あなたはここにいくつかのより多くの例を見ることができますgnu.org/software/coreutils/manual/html_node/env-invocation.html
機能について厳密に言うと、機能env
の巨大なセットを持つバイナリであり、その1つは環境変数を印刷するのに対して、環境変数を印刷するprintenv
だけです。
要約すると、envでの作業に慣れている場合はenv
(これが慣れているからです)印刷に進みます。そうでない場合は、通常printenv
より速く覚えられます。
話をするときに差は事実上ありませんprintenv
VS env
だけの環境変数を印刷します。確認したところ、envはわずかに重く(約5 KB余分に)、それらのパフォーマンス(時間内)はまったく同じようです。
これで解決することを願っています!:)
2つのバイナリの履歴やレガシーに関係なく、2つのバイナリの出力の違いを本当に知りたい場合は、いくつかのユーティリティを実行してこの違いを測定できます。debianでは、カスタム環境変数に応じて異なるいくつかのことを実行しました。
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
そのため、2つに1つの行があり、その行は番号41であり、コマンドで使用されるバイナリを規定していると思います。追加の引数なしで、これらは私にとって事実上同一の情報を報告します。