ใครตั้งค่าตัวแปรสภาพแวดล้อม $ USER และ $ USERNAME


34

นอกจากนี้ตัวแปรเหล่านี้จะจับคู่กับชื่อผู้ใช้ที่เข้าสู่ระบบในปัจจุบันอยู่เสมอหรือไม่ ฉันสามารถสมมติความพร้อมใช้งานในระบบ Unix (- like) อื่น ๆ ได้หรือไม่?

ฉันยังสงสัยด้วยว่าทำไมจึงใช้whoamiแทนการอ่านตัวแปรเหล่านี้


2
ดูที่manหน้าwhoamiรายงานชื่อที่เชื่อมโยงกับ ID ผู้ใช้ที่มีประสิทธิภาพของคุณ ซึ่งหมายความว่ามันจะส่งคืนสิ่งที่แตกต่างถ้าคุณใช้sudoหรือเรียกใช้ปฏิบัติการ setuid หากคุณได้sudoตั้งค่าลองsudo whoamiตัวอย่าง
โจเซฟอาร์

4
USERและUSERNAMEเป็นตัวแปรสภาพแวดล้อมทั่วไปซึ่งหมายความว่าหากคุณต้องการคุณสามารถตั้งค่าให้เป็นค่าใดก็ได้ USER=xyzเพียงพิมพ์ กล่าวอีกนัยหนึ่งแม้ว่าตัวแปรเหล่านั้นจะมีอยู่ แต่ก็ไม่รับประกันว่าค่าเหล่านั้นจะตรงกับชื่อผู้ใช้ที่เข้าสู่ระบบในปัจจุบัน
Uwe

@Uwe โดยguaranteeฉันหมายถึงค่าเริ่มต้น (สมมติว่าผู้ใช้ไม่ได้เปลี่ยน)
tshepang

2
@Tshepang ในฐานะที่เป็นติดตามความคิดเห็นแรกของฉัน: เปรียบเทียบผลลัพธ์ของsudo whoamiและsudo echo $USER
โจเซฟอาร์

2
@JosephR สำหรับการsudo echo $USERขยายเปลือก$USER, แล้วsudoเรียก แน่นอนว่ามันไม่ได้สร้างผลลัพธ์ที่เหมือนwhoamiกัน ชอบsudo whoami, sudo sh -c 'echo $USER'ไม่ (โดยทั่วไป) rootเอาท์พุท เกี่ยวกับความคิดเห็นของคุณเกี่ยวกับการwhoamiใช้ EUIDโปรดทราบว่าsudo whoamiจะให้ผลลัพธ์rootแม้ว่าจะwhoamiใช้ UID ก็ตาม sudoตั้งค่าทั้ง EUID และ UID สำหรับคำสั่งที่เรียกใช้ (ยกเว้นในสถานการณ์ที่ผิดปกติอย่างยิ่งที่คุณกำหนดค่าให้ทำงานอย่างอื่น) เปรียบเทียบไปsudo id -u sudo id -ru
Eliah Kagan

คำตอบ:


29

มันเข้าสู่ระบบ

หน้า man Linux login (1)พูดว่า:

ค่าสำหรับ$ HOME , $ USER , $ SHELL , $ PATH , $ LOGNAMEและ $ MAILจะถูกตั้งค่าตามฟิลด์ที่เหมาะสมในรายการรหัสผ่าน

หน้าคนเข้าสู่ระบบ FreeBSD (1)พูดว่า:

เข้าสู่ระบบสาธารณูปโภคเข้าข้อมูลสู่สิ่งแวดล้อม (ดู สภาพแวดล้อม (7) ) ระบุไดเรกทอรีบ้านของผู้ใช้ (HOME) คำสั่งล่าม (Shell), เส้นทางการค้นหา (PATH) ประเภทอาคาร (คำ) และชื่อผู้ใช้ (ทั้ง LOGNAME และผู้ใช้) .

หน้าคู่มือNetBSD , OpenBSDและOS Xพูดแบบเดียวกัน

นี่คือซอร์สโค้ดจากการเข้าสู่ระบบ 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);

นี่คือซอร์สโค้ดจากการเข้าสู่ระบบ FreeBSD:

(void)setenv("LOGNAME", username, 1);
(void)setenv("USER", username, 1);
(void)setenv("PATH", rootlogin ? _PATH_STDPATH : _PATH_DEFPATH, 0);

2
บน Fedora 16 กล่องของฉันฉันมีทั้งสองUSERและชุดและผลตอบแทนเพียงคำสั่งของคุณUSERNAME LOGNAME
Joseph R.

1
@JosephR. โชคไม่ดีที่ฉันไม่มี Fedora อยู่ในมือ แต่ฉันได้ดูแหล่งที่มาของ FreeBSD ด้วยดู UPD ..
poige

แต่นี่ไม่ใช่กรณีของ Fedora ทั้งหมดที่ฉันพูดคือloginดูเหมือนจะไม่เป็นเพียงสิ่งเดียวที่กำหนดตัวแปรเหล่านี้
โจเซฟอาร์

1
โปรดทราบว่า Linux เป็นเพียงเคอร์เนล แต่ไม่มีloginคำสั่ง ระบบปฏิบัติการที่ใช้ Linux เป็นเคอร์เนลสามารถใช้งานได้ตามต้องการ ตัวอย่างเช่นระบบที่ใช้เดเบียนมักจะใช้ระบบจาก shadow-utils ไม่ใช่ util-linux
Stéphane Chazelas

1
โปรดทราบว่าloginมักจะไม่เรียกใช้เมื่อลงชื่อเข้าใช้ผ่านsshหรือโดยผู้จัดการการลงชื่อเข้าใช้แบบกราฟิกส่วนใหญ่
Stéphane Chazelas

11

ไม่มีกฎ เปลือกหอยบางคนชอบtcshหรือชุดzsh ชุด$LOGNAMEzsh$USER

มันอาจจะถูกกำหนดโดยบางสิ่งบางอย่างที่คุณเข้าสู่ระบบเช่นlogin(ตามที่เรียกโดยgettyเมื่อเข้าสู่ระบบในสถานีและบางครั้งโดยสิ่งอื่น ๆ เช่นin.rlogind) cron, su, sudo, sshd, rshdผู้จัดการการเข้าสู่ระบบกราฟิกหรืออาจจะไม่ได้

หากมีการเข้าสู่ระบบในประสบการณ์ของฉัน$USERโดยทั่วไปมีการตั้งค่า (แต่มันอาจไม่ได้รับการปรับปรุงหลังจากการเปลี่ยน ID ผู้ใช้ (ผ่านคำสั่ง setuid) ภายในเซสชันการเข้าสู่ระบบนั้น POSIX ต้อง$LOGNAMEมีการตั้งค่าเมื่อเข้าสู่ระบบ (และcron)

เพื่อให้ได้ชื่อเข้าสู่ระบบได้อย่างดีที่สุดคือการใช้lognameคำสั่ง (ถ้าไม่มีการเข้าสู่ระบบใด ๆ มันอาจไม่ส่งคืนอะไรเลย) id -uที่จะได้รับรหัสผู้ใช้ที่ใช้ id -unจะได้รับหนึ่งชื่อผู้ใช้ที่สอดคล้องกับรหัสผู้ใช้ที่มีประสิทธิภาพปัจจุบัน: ในการรับทั้งหมด (ส่วนใหญ่มีชื่อผู้ใช้เพียงชื่อเดียวต่อ ID ผู้ใช้ แต่ไม่รับประกัน):

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

แม้ว่ามันอาจไม่ทำงานบนระบบที่ฐานข้อมูลผู้ใช้ไม่สามารถระบุได้ (เช่นบางครั้งเกิดขึ้นกับฐานข้อมูลผู้ใช้เครือข่ายเป็นต้น)


3

คุณอาจต้องการใช้มาตรฐานPOSIXที่นี่เนื่องจากในบางช่วงเวลาคุณอาจสนใจไม่ใช่แค่การเข้าสู่ระบบของผู้ใช้ (จัดการโดยloginโปรแกรม) แต่ยังมีcronงานและสิ่งที่ชอบ

ดังนั้นคุณควรรู้ว่า POSIX ต้องแต่ไม่$LOGNAME $USERเช่น$USERอาจไม่ได้รับการกำหนดโดย cron ดังที่ได้กล่าวไว้ในคำตอบของ Keith Thompsonซึ่งได้อ้างอิงถึงประวัติความเป็นมาของวิธีการที่เกี่ยวข้องกับประวัติความเป็นมาของ System-V กับ BSD:

... อย่างน้อยในระบบของฉัน (Ubuntu 14.04) ตัวแปรสภาพแวดล้อม $ USER ไม่ได้ถูกตั้งค่าสำหรับงาน cron แต่คุณสามารถใช้ $ LOGNAME ซึ่งเป็นส่วนหนึ่งของสภาพแวดล้อมสำหรับงาน cron

อ้างอิงจากหน้าenviron (7) man man (พิมพ์ man environ เพื่ออ่าน), $ USER ถูกใช้โดยโปรแกรมที่ได้รับจาก BSD และ $ LOGNAME ถูกใช้โดยโปรแกรมที่ได้มาจาก System-V


1

หากคุณต้องการใช้ตัวแปรสภาพแวดล้อม (แทนwhoamiหรือgetpwentและgetpwnam) และคุณไม่แน่ใจว่าพวกเขาจะตั้งค่าแบบเดียวกันในทุกระบบ * NIX ทุกครั้งให้ลองใช้วิธีนี้ใน bash:

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

หากยังคงว่างเปล่าหลังจากนั้นแสดงว่าคุณอยู่ในระบบที่ค่อนข้างลึกลับ ;)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.