Siapa yang menetapkan variabel lingkungan $ USER dan $ USERNAME?

34

Juga, akankah variabel-variabel ini selalu cocok dengan nama pengguna yang saat ini login (mereka lakukan di sistem Debian saya)? Bisakah saya menganggap ketersediaannya di sistem Unix (-seperti) lainnya?

Saya juga ingin tahu mengapa orang akan menggunakan whoamidaripada hanya membaca variabel-variabel ini.

tepang
sumber
2
Melihat manhalaman tersebut, whoamimelaporkan nama yang terkait dengan ID pengguna Anda yang efektif. Yang berarti itu akan mengembalikan sesuatu yang berbeda jika Anda menggunakan sudoatau menjalankan setuid yang dapat dieksekusi. Jika sudah sudodiatur, coba sudo whoamimisalnya.
Joseph R.
4
USERdan USERNAMEmerupakan variabel lingkungan biasa, yang berarti bahwa, jika Anda mau, Anda bisa mengaturnya ke nilai arbitrer. Cukup ketik USER=xyz. Dengan kata lain, bahkan jika variabel-variabel itu ada, tidak ada jaminan bahwa nilainya cocok dengan nama pengguna yang saat ini masuk.
Uwe
@Uwe By guarantee, maksud saya secara default (yaitu asumsi pengguna tidak mengubahnya).
tshepang
2
@Tepang, sebagai tindak lanjut dari komentar pertama saya: bandingkan hasil sudo whoamidansudo echo $USER
Joseph R.
2
@ JosephephR. Sebab sudo echo $USER, shell mengembang $USER, lalu memanggil sudo. Jadi tentu saja tidak menghasilkan output yang sama dengan whoami. Seperti sudo whoami, sudo sh -c 'echo $USER'apakah (biasanya) output root. Mengenai komentar Anda tentang whoamimenggunakan EUID , perhatikan bahwa sudo whoamiakan menghasilkan rootbahkan jika whoamimenggunakan UID. sudoset kedua EUID dan UID untuk perintah berjalan (kecuali dalam situasi yang sangat tidak biasa yang Anda secara eksplisit mengkonfigurasi untuk berperilaku sebaliknya). Bandingkan sudo id -udengan sudo id -ru.
Eliah Kagan

Jawaban:

29

Ini masuk .

Halaman login Linux (1) mengatakan:

Nilai $ HOME , $ USER , $ SHELL , $ PATH , $ LOGNAME , dan $ MAIL diatur sesuai dengan bidang yang sesuai dalam entri kata sandi.

Halaman login FreeBSD (1) mengatakan:

The masuk utilitas memasukkan informasi ke lingkungan (lihat environ (7) ) menentukan direktori pengguna rumah (HOME), perintah interpreter (SHELL), pencarian jalan (PATH), jenis terminal (JANGKA) dan nama pengguna (baik LOGNAME dan PENGGUNA) .

The NetBSD , OpenBSD dan OS X man mengatakan hal yang sama.

Berikut kode sumber dari login util-linux:

setenv("HOME", pwd->pw_dir, 0); /* legal to override */
setenv("USER", pwd->pw_name, 1);
setenv("SHELL", pwd->pw_shell, 1);
/* ... */
setenv("LOGNAME", pwd->pw_name, 1);

Berikut kode sumber dari login FreeBSD:

(void)setenv("LOGNAME", username, 1);
(void)setenv("USER", username, 1);
(void)setenv("PATH", rootlogin ? _PATH_STDPATH : _PATH_DEFPATH, 0);
poige
sumber
2
Pada kotak Fedora 16 saya, saya memiliki keduanya USERdan USERNAMEmengatur dan perintah Anda hanya kembali LOGNAME.
Joseph R.
1
. @JosephR, sayangnya saya tidak memiliki Fedora di tangan tapi aku sudah melihat ke sumber FreeBSD juga, lihat UPD ..
poige
Tapi ini jelas tidak terjadi pada Fedora. Yang saya katakan adalah, loginsepertinya bukan satu-satunya pengaturan variabel-variabel ini.
Joseph R.
1
Perhatikan bahwa Linux hanyalah sebuah kernel, tidak memiliki loginperintah. OS yang menggunakan Linux sebagai kernelnya bebas untuk menggunakan implementasi apa pun yang mereka suka. Sebagai contoh, sistem berbasis Debian cenderung menggunakan yang dari shadow-utils, bukan util-linux.
Stéphane Chazelas
1
Catatan yang loginsering tidak dipanggil ketika login lebih sshatau oleh sebagian besar manajer login grafis.
Stéphane Chazelas
11

Tidak ada aturan. Beberapa kerang suka tcshatau zshdiatur $LOGNAME. zshset $USER.

Ini mungkin diatur oleh beberapa hal yang login Anda dalam seperti login(seperti yang dipanggil oleh gettyketika login pada terminal dan kadang-kadang oleh hal-hal lain seperti in.rlogind), cron, su, sudo, sshd, rshd, manajer login grafis atau mungkin tidak.

Jika ada login, menurut pengalaman saya, $USERumumnya diatur (tetapi mungkin tidak diperbarui setelah perubahan id pengguna (melalui perintah setuid) dalam sesi login tersebut. POSIX mengharuskan yang $LOGNAMEditetapkan saat login (dan cron).

Untuk mendapatkan nama login dengan mudah, yang terbaik adalah menggunakan lognameperintah (jika belum ada login, mungkin tidak mengembalikan apa-apa). Untuk mendapatkan id pengguna, gunakan id -u. Untuk mendapatkan satu nama yang sesuai dengan saat ini efektif user id: id -un. Untuk mendapatkan semuanya (sebagian besar waktu, hanya ada satu nama pengguna per id pengguna, tetapi itu tidak dijamin):

perl -le 'while ($n = getpwent()) {print $n if getpwnam($n) == $>}'

Meskipun itu mungkin tidak bekerja pada sistem di mana basis data pengguna tidak dapat disebutkan (seperti yang terjadi kadang-kadang dengan database pengguna jaringan misalnya).

Stéphane Chazelas
sumber
3

Anda mungkin ingin mengandalkan standar POSIX di sini, karena pada suatu saat Anda mungkin akan peduli tidak hanya login pengguna (dikelola oleh loginprogram) tetapi juga cronpekerjaan dan sejenisnya.

Karena itu, Anda harus tahu bahwa POSIX membutuhkan $LOGNAMEtetapi tidak $USER. Misalnya $USERmungkin tidak diatur oleh cron, seperti yang ditunjukkan dalam jawaban oleh Keith Thompson , yang juga merujuk beberapa sejarah tentang bagaimana ini berkaitan dengan sejarah System-V vs BSD:

... setidaknya di sistem saya (Ubuntu 14.04) variabel lingkungan $ USER tidak disetel untuk pekerjaan cron. Sebagai gantinya, Anda dapat menggunakan $ LOGNAME, yang merupakan bagian dari lingkungan untuk pekerjaan cron.

Menurut halaman manual Environmental (7) (tipe manviron untuk membacanya), $ USER digunakan oleh program-program yang diturunkan BSD dan $ LOGNAME digunakan oleh program-program yang diturunkan oleh System-V.

nealmcb
sumber
1

Jika Anda ingin menggunakan variabel lingkungan (bukan whoamiatau getpwentdan getpwnam) dan Anda tidak yakin apakah mereka selalu diatur dengan cara yang sama pada semua sistem * NIX, coba ini di bash:

THIS_USER=${USER:-${USERNAME:-${LOGNAME}}}
echo ${THIS_USER}

Jika masih kosong setelah semua itu, maka Anda berada pada sistem yang agak esoteris. ;)

Jesse Chisholm
sumber