“env”和“printenv”有什麼區別?
env
這兩個命令和有什麼區別printenv
?它們都顯示環境變數,除了_
.有兩個命令而不是一個命令是否有任何歷史原因?
有兩個命令而不是一個命令是否有任何歷史原因?
有,只是歷史的方式。
printenv
Bill Joy於 1979 年為 BSD編寫了第一個版本的命令。- UNIX System III
env
在 1980 年引入了命令。- GNU
env
在 1986 年緊隨 UNIX 系統。- BSD
env
在 1988 年緊隨 GNU/UNIX 系統。- MINIX
printenv
在 1988 年緊隨 BSD。- GNU 在 1989 年緊隨 MINX/BSD
printenv
。- GNU shell 程式實用程序 1.0 包括在 1991 年
printenv
。env
- GNU Shell Utilities 於 2002 年合併到 GNU coreutils,這就是你現在在 GNU/Linux 中找到的。
請注意,“followed”並不意味著原始碼相同,可能它們被重寫以避免許可訴訟。
所以,這兩個命令存在的原因是因為比爾喬伊
printenv
甚至在env
存在之前就寫了。經過 10 年的合併/兼容性和 GNU 遇到它,您現在可以在同一頁面上看到兩個相似的命令。這段歷史表明如下:( 我試圖最小化答案,在這裡只提供了2個基本的原始碼片段。其餘的你可以點擊附加的連結查看更多)
$$ fall of 1975 $$
同樣在 1975 年秋天抵達的還有兩名未被注意到的研究生,比爾·喬伊和查克·黑利。他們都對新系統產生了直接的興趣。最初,他們開始研究湯普森在 11/70 機房附近閒逛時一起破解的 Pascal 系統。
$$ 1977 $$
Joy 開始編譯第一個伯克利軟體發行版 (1BSD),該發行版於 1978 年 3 月 9 日發布。 //rf: https://en.wikipedia.org/wiki/Berkeley_Software_Distribution
$$ February, 1979 $$
1979(參見“Bill Joy,UCB,1979 年 2 月”)/1980(參見“版權
$$ $$=") , 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
$$ June, 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第一版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 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
$$ October 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 $$
GNU 的第一個版本
printenv
,參考$$ August 12, 1993 $$. $$ July 16, 1991 $$
“Shellutils” - GNU shell 程式實用程序 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 是 nice nohup stty uname
$$ August 12, 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 實用程序 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
$$ November 1993 $$
FreeBSD 的第一個版本發布。//rf: https://en.wikipedia.org/wiki/FreeBSD
$$ september 1, 2002 $$
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
也可以這樣做- 禁用 shell 內置,但也可以使用
enable
cmd 實現。- 設置變數但沒有意義,因為某些 shell 已經可以在沒有 的情況下做到這一點
env
,例如$ HOME=/dev HOME=/tmp USER=root /bin/bash -c “cd ~; pwd”
/tmp 4.
#!/usr/bin/env python``env
標頭,但如果不在 /usr/bin 中,仍然不可移植 5.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
會減慢圖像的顯示速度。 6.target_PATH="$PATH:$(sudo printenv PATH)";
直接使用根路徑而不需要進一步解析env
or的輸出很有用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:~$