ความแตกต่างระหว่างสองคำสั่งenv
และprintenv
คืออะไร? _
พวกเขาทั้งสองแสดงตัวแปรสภาพแวดล้อมและการส่งออกจะตรงเดียวกันนอกเหนือจาก
มีเหตุผลทางประวัติศาสตร์หรือไม่ที่มีสองคำสั่งแทนที่จะเป็นหนึ่งคำสั่ง?
ความแตกต่างระหว่างสองคำสั่งenv
และprintenv
คืออะไร? _
พวกเขาทั้งสองแสดงตัวแปรสภาพแวดล้อมและการส่งออกจะตรงเดียวกันนอกเหนือจาก
มีเหตุผลทางประวัติศาสตร์หรือไม่ที่มีสองคำสั่งแทนที่จะเป็นหนึ่งคำสั่ง?
คำตอบ:
มีเหตุผลทางประวัติศาสตร์หรือไม่ที่มีสองคำสั่งแทนที่จะเป็นหนึ่งคำสั่ง?
มีลักษณะประวัติศาสตร์เพียง
printenv
คำสั่งเวอร์ชันแรกในปี 1979 สำหรับ BSDenv
คำสั่งในปี 1980env
ในปี 1986env
ในปี 1988printenv
ในปี 1988printenv
ในปี 1989printenv
และenv
ในปี 1991โปรดทราบว่า "ติดตาม" ไม่ได้หมายความว่าซอร์สโค้ดเหมือนกันอาจเป็นไปได้ว่าพวกเขาจะถูกเขียนใหม่เพื่อหลีกเลี่ยงการฟ้องร้องดำเนินคดี
ดังนั้นสาเหตุที่คำสั่งทั้งสองนั้นมีอยู่เพราะเมื่อจอยเขียนprintenv
ตอนนั้นสิ่งที่env
ยังไม่เกิดขึ้น หลังจากการผสาน / ความเข้ากันได้เป็นเวลา 10 ปีและ GNU เจอแล้วตอนนี้คุณเห็นคำสั่งที่คล้ายกันทั้งสองที่หน้าเดียวกัน
ประวัตินี้ระบุไว้ดังต่อไปนี้: (ฉันพยายามที่จะลดคำตอบให้เหลือเพียง 2 ซอร์สโค้ดที่สำคัญที่นี่ส่วนที่เหลือคุณสามารถคลิกลิงค์ที่แนบมาเพื่อดู)
[ฤดูใบไม้ร่วงปี 2518]
เมื่อถึงฤดูใบไม้ร่วงปี 2518 นักศึกษาบัณฑิตสองคนที่ไม่มีใครสังเกตเห็นคือ Bill Joy และ Chuck Haley; พวกเขาทั้งสองสนใจในระบบใหม่ทันที เริ่มแรกพวกเขาเริ่มทำงานกับระบบปาสคาลที่ ธ อมป์สันแฮ็คด้วยกันขณะที่แขวนอยู่รอบ ๆ ห้องเครื่อง 11/70
[1977]
Joy เริ่มรวบรวม Berkeley Software Distribution (1BSD) ครั้งแรกซึ่งเปิดตัวเมื่อวันที่ 9 มีนาคม 2521 // rf: https://en.wikipedia.org/wiki/Berkeley_Software_Distribution
[กุมภาพันธ์, 1979]
2522 (ดู "บิลจอย UCB กุมภาพันธ์ 2522") / 2523 (ดู "ลิขสิทธิ์ [] ="), 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
3BSD คำสั่ง printenv ปรากฏใน 3.0 BSD // rf: http://www.freebsd.org/cgi/man.cgi?query=printenv&sektion=1#end 3.0 BSD เปิดตัวในปี 1979 // rf: http://gunkies.org/wiki/3_BSD
2BSD คำสั่ง printenv ปรากฏเป็นครั้งแรกใน 2BSD // rf: http://man.openbsd.org/printenv.1
[มิถุนายน 1980]
UNIX รีลีส 3.0 หรือ "UNIX System III" // rf: ftp://pdp11.org.ru/pub/unix-archive/PDP-11/Distribution/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
[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 ตุลาคม 2531]
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
อ้างถึง [12 สิงหาคม 1993]
[16 กรกฎาคม 1991]
"Shellutils" - โปรแกรมอรรถประโยชน์การเขียนโปรแกรมเชลล์ของ GNU 1.0 เปิดตัว // rf: https://groups.google.com/forum/#!topic/gnu.announce/xpTRtuFpNQc
โปรแกรมในแพ็คเกจนี้คือ:
basename date dirname envกลุ่ม expr id logname pathchk printenv printf sleep tee tty whoami ใช่ดี nohup stty uname
[12 สิงหาคม 2536]
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/ รุ่นที่
/* printenv -- print all or part of environment
Copyright (C) 1989, 1991 Free Software Foundation.
...
[1993]
printenv.c ซึ่งพบในซอร์สโค้ด DSLinux ในปี 2549 // 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]
FreeBSD เวอร์ชันแรกเปิดตัวแล้ว // rf: https://en.wikipedia.org/wiki/FreeBSD
[กันยายน 1, 2002]
http://git.savannah.gnu.org/cgit/coreutils.git/tree/README-package-renamed-to-coreutils
fileutils ของ GNU, textutils และ sh-utils (ดู "Shellutils" ที่ 16 กรกฎาคม 1991 ข้างบน) แพ็คเกจได้ถูกรวมเข้าเป็นหนึ่งเดียวเรียกว่า 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
ปิดการใช้งาน env ทั้งหมด ฉันพบว่ามีประโยชน์ในการหาตัวแปรสภาพแวดล้อมที่สำคัญสำหรับบางโปรแกรมเพื่อให้ทำงาน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
ไม่ได้ (GNU coreutils ใน Ubuntu 15.10)
จากหน้าคน:
env - รันโปรแกรมในสภาพแวดล้อมที่ถูกปรับเปลี่ยน
...
printenv - พิมพ์ทั้งหมดหรือบางส่วนของสภาพแวดล้อม
ควรอธิบายให้สวย
printenv
เพียงพิมพ์ตัวแปรทั้งหมดของสภาพแวดล้อมปัจจุบัน ด้วยenv
คุณสามารถเตรียมสภาพแวดล้อมเดียวกันกับการปรับเปลี่ยนบางอย่างถ้าจำเป็นและเรียกใช้แอปในนั้น
ls
เป็นไบนารี แต่เป็นนามแฝงร่วมกันซึ่งมักจะเพียงแค่ขยายll
และเป็นสองไบนารีที่แตกต่างกันฉันไม่แน่ใจว่าคนแรกที่ได้รับการแนะนำว่า คุณสามารถดูตัวอย่างเพิ่มเติมได้ที่นี่gnu.org/software/coreutils/manual/html_node/env-invocation.htmlls -l
printenv
env
พูดคุยเกี่ยวกับฟังก์ชันการทำงานอย่างเข้มงวดenv
เป็นไบนารีที่มีชุดคุณลักษณะขนาดใหญ่หนึ่งในนั้นคือการพิมพ์ตัวแปรสภาพแวดล้อมในขณะที่printenv
เพียงพิมพ์ตัวแปรสภาพแวดล้อม
โดยสรุปหากคุณคุ้นเคยกับการทำงานกับ env คุณจะได้ไปกับenv
การพิมพ์พวกเขา (เพราะนั่นคือสิ่งที่คุณคุ้นเคย) และหากคุณไม่ได้ใช้คุณจะจำprintenv
ได้เร็วขึ้น
มีจริงไม่มีความแตกต่างเมื่อพูดถึงprintenv
VS env
เพียงพิมพ์ตัวแปรสิ่งแวดล้อม ฉันเพิ่งตรวจสอบและ env หนักกว่าเล็กน้อย (ประมาณ 5 KB เพิ่มเติม) และประสิทธิภาพ (ในเวลา) ดูเหมือนว่าจะเหมือนกันทุกประการ
หวังว่านี่จะเป็นการล้างออก! :)
หากคุณต้องการทราบว่าเอาต์พุตของสองไบนารีที่ต่างกันโดยไม่คำนึงถึงประวัติและมรดกของมันนั้นเป็นอย่างไรคุณสามารถรันยูทิลิตี้บางอย่างเพื่อวัดความแตกต่างนี้ เดเบียนฉันวิ่งไปสองสามอย่างที่จะแตกต่างกันไปขึ้นอยู่กับสภาพแวดล้อมที่กำหนดเอง:
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 ซึ่งฉันเดากำหนดไบนารีที่ใช้ในคำสั่ง หากไม่มีข้อโต้แย้งเพิ่มเติมรายงานเหล่านี้จะเป็นข้อมูลเหมือนกันสำหรับฉัน