env
2つのコマンドの違いは何ですかprintenv
?どちらも環境変数を表示し、それを除いて出力は同じです_
。
1つではなく2つのコマンドを使用する歴史的な理由はありますか?
答え1
1つではなく2つのコマンドを使用する歴史的な理由はありますか?
歴史がそうです。
歴史
printenv
Bill Joyは1979年にBSDコマンドの最初のバージョンを作成しました。- UNIX System III
env
では、1980年にコマンドを導入しました。 - GNUはUNIXシステムに続いて1986年に登場しました
env
。 - BSDはGNU/UNIXシステムに続いて1988年に登場しました
env
。 - MINIXは1988年にBSDの後に続きました
printenv
。 - GNUは1989年にMINX / BSDの後に続きました
printenv
。 - 1991
printenv
GNUシェルプログラミングユーティリティ1.0が含まれています。env
- GNU Shell Utilitiesは2002年にGNU coreutilsにマージされ、これが今日GNU / Linuxで見られるものです。
「follow」は、ソースコードが同じであるという意味ではなく、ライセンス訴訟を避けるために書き直された可能性があります。
したがって、これら2つのコマンドは、Bill Joyが存在するprintenv
前に作成したために存在しますenv
。 10年間のマージ/互換性とGNUに会った後、同じページに2つの同様のコマンドを表示できるようになりました。
この記録は以下を示しています。 (回答を最小限に抑えようとしましたが、ここでは2つの基本的なソースコードの断片だけを提供しました。
[1975年秋]
1975年の秋には、目立たない2人の大学院生、ビル・ジョイ(Bill Joy)とチャック・ヘイリー(Chuck Haley)も到着しました。彼らはすべて新しい制度に即時の関心を示した。当初、彼らはThompsonが11月70日にコンピュータルームで遊んで一緒に解読したPascalシステムの仕事を始めました。
[1977]
Joyは1978年3月9日にリリースされた最初のBerkeley Software Distribution(1BSD)のコンパイルを開始しました。 //rf:https://en.wikipedia.org/wiki/Berkeley_Software_Distribution
[1979年2月]
1979("Bill Joy, UCB February, 1979"を参照)/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 1979年に導入された3.0 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の最初のprintenvマニュアル//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 最初のリリース //rf:https://en.wikipedia.org/wiki/Andrew_S._Tanenbaum
- Tanenbaumは、IBM PC用のMINIX(MINI-unIX)と呼ばれるUNIXレプリカを作成しました。オペレーティングシステムのしくみを理解したい学生や他のユーザーを対象としています。
[1988]
BSD最初の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
... 32932190 /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
このパッケージに含まれるプログラムは次のとおりです。
デフォルト名日付ディレクトリ名環境expr グループ ID ログ名パス chk印刷環境 printf sleep Tee tty whoami はい、いいね 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シェルユーティリティ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 。 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
。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:~$
答え2
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
(フリーBSD)man 1 printenv
(フリーBSD)
答え3
答え4
厳密に言えば、env
多くの機能を備えたバイナリであり、その1つは環境変数を印刷し、printenv
環境変数のみを印刷することです。
全体として、envの使用に精通している場合はenv
印刷を続けます(なぜならこれは慣れているからです)。そうでなければ、一般的にprintenv
早く覚えています。
printenv
環境変数について話しているだけで印刷することにはenv
実際に違いはありません。私はちょうど確認しましたが、envはやや重く(約5KB以上)、パフォーマンス(時間の経過)はまったく同じようです。
これが問題を解決することを願っています! :)