Apa perbedaan antara kedua perintah env
dan printenv
? Mereka berdua menunjukkan variabel lingkungan, dan output persis sama selain _
.
Apakah ada alasan historis mengapa ada dua perintah, bukan satu?
sumber
Apa perbedaan antara kedua perintah env
dan printenv
? Mereka berdua menunjukkan variabel lingkungan, dan output persis sama selain _
.
Apakah ada alasan historis mengapa ada dua perintah, bukan satu?
Apakah ada alasan historis mengapa ada dua perintah, bukan satu?
Hanya ada cara sejarah.
printenv
perintah pada tahun 1979 untuk BSD.env
perintah pada tahun 1980.env
pada tahun 1986.env
pada tahun 1988.printenv
pada tahun 1988.printenv
pada tahun 1989.printenv
dan env
pada tahun 1991.Perhatikan bahwa "diikuti" tidak berarti kode sumbernya sama, mungkin kode tersebut ditulis ulang untuk menghindari gugatan lisensi.
Jadi alasan mengapa kedua perintah itu ada adalah karena ketika Bill Joy menulis printenv
waktu itu, env
belum ada. Setelah 10 tahun penggabungan / kompatibilitas dan GNU menemukannya, Anda sekarang melihat kedua perintah serupa di halaman yang sama.
Riwayat ini ditunjukkan sebagai berikut: (Saya mencoba meminimalkan jawabannya dan hanya menyediakan 2 kode sumber penting di sini, sisanya Anda dapat mengklik tautan terlampir untuk melihat)
[musim gugur 1975]
Juga tiba pada musim gugur 1975 adalah dua mahasiswa pascasarjana yang tidak diketahui, Bill Joy dan Chuck Haley; mereka berdua segera tertarik pada sistem yang baru. Awalnya mereka mulai bekerja pada sistem Pascal yang telah diretas Thompson bersama sambil berkeliaran di ruang mesin 11/70.
[1977]
Joy mulai menyusun Berkeley Software Distribution (1BSD) pertama, yang dirilis pada 9 Maret 1978. // rf: https://en.wikipedia.org/wiki/Berkeley_Software_Distribution
[Februari, 1979]
1979 (lihat "Bill Joy, UCB Februari, 1979") / 1980 (lihat "hak cipta [] ="), 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]
Sulit untuk menentukan dirilis dalam 2BSD ATAU 3BSD // rf: https://en.wikipedia.org/wiki/Berkeley_Software_Distribution
3BSD Perintah printenv muncul di 3.0 BSD. // rf: http://www.freebsd.org/cgi/man.cgi?query=printenv&sektion=1#end 3.0 BSD diperkenalkan pada 1979 // rf: http://gunkies.org/wiki/3_BSD
2BSD Perintah printenv pertama kali muncul di 2BSD // rf: http://man.openbsd.org/printenv.1
[Juni, 1980]
UNIX Release 3.0 ATAU "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 manual pertama // rf: http://minnie.tuhs.org/cgi-bin/utree.pl?file=2.11BSD/src/man/man1/printenv.1 tetapi saya tidak dapat menemukan manual yang terkait dengan env , yang paling dekat adalah getenv dan environment // http://minnie.tuhs.org/cgi-bin/utree.pl?file=2.11BSD/src/man
[1986]
Versi pertama 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 dirilis // 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 Oktober 1988]
MINIX versi 1.3 // rf: https://groups.google.com/forum/#!topic/comp.os.minix/cQ8kaiq1hgI
... 32932 190 /minix/commands/printenv.c //printenv.c sudah ada
// rf: http://www.informatica.co.cr/linux/research/1990/0202.htm
[1989]
Versi pertama GNU printenv
, lihat [12 Agustus 1993].
[16 Juli 1991]
"Shellutils" - Utilitas pemrograman shell GNU 1.0 dirilis // rf: https://groups.google.com/forum/#!topic/gnu.announce/xpTRtuFpNQc
Program-program dalam paket ini adalah:
basename date dirname env expr grup id logname pathchk printenv printf sleep tee tty whoami yes nice nohup stty uname
[12 Agustus 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]
printenv.c yang ditemukan pada kode sumber DSLinux pada tahun 2006 // 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]
Versi pertama FreeBSD dirilis. // rf: https://en.wikipedia.org/wiki/FreeBSD
[1 september 2002]
http://git.savannah.gnu.org/cgit/coreutils.git/tree/README-package-renamed-to-coreutils
Fileutils GNU, textutils, dan sh-utils (lihat "Shellutils" pada 16 Juli 1991 di atas) paket telah digabung menjadi satu, yang disebut GNU coreutils.
Secara keseluruhan, env
use case dibandingkan dengan printenv
:
printenv
dapat melakukan hal yang samaenable
cmd juga.atur variabel tetapi tidak berguna karena beberapa shell sudah dapat melakukannya tanpa env
, misalnya
$ HOME = / dev HOME = / tmp PENGGUNA = root / bin / bash -c "cd ~; pwd"
/ tmp
#!/usr/bin/env python
sundulan, tetapi tetap tidak portabel jika env
tidak di / usr / bin
env -i
, nonaktifkan semua env. Saya merasa berguna untuk mencari tahu variabel lingkungan kritis untuk program tertentu agar dapat dijalankan crontab
. misal [1] Dalam mode interaktif, jalankan declare -p > /tmp/d.sh
untuk menyimpan variabel atribut. [2] Dalam /tmp/test.sh
, tulis: . /tmp/d.sh;
eog /home/xiaobai/Pictures/1.jpg
[3] Sekarang jalankan env -i bash /tmp/test.sh
[4] Jika berhasil menampilkan gambar, hapus setengah dari variabel /tmp/d.sh
dan jalankan env -i bash /tmp/test.sh
lagi. Jika sesuatu gagal, urungkan. Ulangi langkah ini untuk mempersempit. [5] Akhirnya saya mencari tahu eog
membutuhkan $DISPLAY
untuk berjalan dalam crontab
, dan tidak ada dari $DBUS_SESSION_BUS_ADDRESS
akan memperlambat tampilan gambar.
target_PATH="$PATH:$(sudo printenv PATH)";
berguna untuk langsung menggunakan path root tanpa harus mem-parsing output env
atau printenv
.
misalnya:
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:~$
Memiliki sudut pandang yang berbeda (dari FreeBSD), Anda memiliki:
Dari
man env
:Dari
man printenv
:Jadi perintah-perintah ini mungkin memiliki efek yang sama tanpa argumen, tetapi
printenv
satu-satunya tujuan adalah untuk menampilkan kunci / nilai lingkungan saat ini sementaraenv
mengarahkannya ke beberapa lingkungan sebelum memanggil biner / skrip lain / apa pun.Apakah lebih jelas seperti ini?
Untuk lebih dikenal:
man 1 env
(FreeBSD)man 1 printenv
(FreeBSD)sumber
env
perintah muncul di 4.4BSD. Opsi -P, -S dan -v ditambahkan dalam FreeBSD 6.0. Theprintenv
perintah muncul di 3.0BSD. Jadi alasan historis tampaknya yangprintenv
datang lebih dulu.env
adalah POSIX 7 ,printenv
bukan (GNU Coreutils di Ubuntu 15.10).sumber
Dari halaman manual:
...
Seharusnya cukup jelas.
sumber
printenv
hanya mencetak semua variabel lingkungan saat ini. Denganenv
Anda dapat menyiapkan lingkungan yang sama dengan beberapa modifikasi jika perlu dan menjalankan aplikasi di dalamnya.ls
adalah biner, tetapill
merupakan alias umum, yang biasanya hanya diperluas kels -l
.printenv
danenv
dua binari yang berbeda, saya tidak yakin mana yang pertama kali diperkenalkan. Anda dapat melihat beberapa contoh lagi di sini gnu.org/software/coreutils/manual/html_node/env-invocation.htmlBerbicara tentang fungsionalitas,
env
adalah biner dengan serangkaian fitur yang besar, salah satunya adalah variabel lingkungan pencetakan, sedangkanprintenv
hanya mencetak variabel lingkungan.Ringkasnya, jika Anda terbiasa bekerja dengan env, Anda akan menggunakannya
env
untuk mencetaknya (karena itulah yang biasa Anda lakukan) dan jika tidak, Anda biasanya akan mengingatprintenv
lebih cepat.Praktis tidak ada perbedaan ketika berbicara tentang
printenv
vsenv
hanya untuk mencetak variabel lingkungan. Saya baru saja memeriksa dan ENV sedikit lebih berat (sekitar 5 KB ekstra), dan kinerja mereka (dalam waktu) tampaknya persis sama.Semoga ini jelas! :)
sumber
Jika Anda benar-benar ingin tahu bagaimana perbedaan keluaran dari dua binari terlepas dari sejarah dan warisan mereka, Anda dapat menjalankan beberapa utilitas untuk mengukur perbedaan ini. Pada debian saya menjalankan beberapa hal yang akan berbeda tergantung pada vars lingkungan kustom:
Kedua output saya memiliki 41 baris
Output: 41c41 <_ = / usr / bin / env ---
Jadi Anda melihat ada satu baris yang berbeda dalam dua dan baris itu adalah nomor 41 yang saya kira menetapkan biner yang digunakan dalam perintah. Tanpa argumen tambahan, ini melaporkan info identik virtual untuk saya.
sumber