เชลล์รู้จักบ้านได้อย่างไร?


25

แต่ละเปลือกมีตัวแปรสภาพแวดล้อม $ ชุดแรก (เช่น: /Users/lotolo) ถ้าฉันอยู่ภายใต้ csh ฉันสามารถunsetenv HOMEและยังถ้าฉันcdฉันจะอยู่ในบ้านของฉัน ฉันได้ทดสอบสิ่งนี้ด้วย bash ( unset HOME) และมันก็เป็นพฤติกรรมเดียวกัน แล้วเชลล์รู้ได้อย่างไรว่าบ้านของฉัน / other_user อยู่ที่ไหน? มันอ่านค่าเหล่านั้นที่ไหน?

สิ่งนี้ไม่ซ้ำกันเนื่องจากคำถามของฉันไม่ใช่ฉันจะรู้ได้อย่างไร แต่เชลล์รู้HOMEได้อย่างไร และพฤติกรรมนี้ก็ขยายไปถึงผู้ใช้รายอื่นเช่นกัน


1
@StephenKitt ไม่ซ้ำกัน ที่นี่เรากำลังพูดถึงพฤติกรรมของเชลล์สำหรับไดเรกทอรีบ้านของผู้ใช้ปัจจุบัน
Stéphane Chazelas

/etc/passwdในกรณีที่เรียบง่ายจาก บางระบบสามารถจัดเก็บข้อมูลดังกล่าวในเซิร์ฟเวอร์ LDAP, NIS และอื่น ๆ
Satō Katsura

1
โปรแกรม (รวมถึงหอย) เพียงแค่โทรgetpwuid(3)หรือคล้ายกัน ระบบบางระบบสามารถกำหนดค่าให้ "re-route" getpwuid(3)เพื่อดึงข้อมูลจาก/etc/passwd, LDAP, NIS, NIS + ฯลฯ
Satō Katsura

@StephenKitt ดูคำตอบของฉัน
Stéphane Chazelas

1
@ GAD3R, ดูการอภิปรายข้างต้น, StephenKitt ได้ชี้ไปที่สำเนาที่ซ้ำกันนั้น (ซึ่งเขาหดกลับมา) แต่ฉันเถียงข้างต้น (และดูคำตอบของฉันด้วย) ว่ามันไม่ซ้ำกัน
Stéphane Chazelas

คำตอบ:


33

ในกรณีของcshและtcshมันจะบันทึกค่าของ$HOMEตัวแปรในเวลาที่เชลล์เริ่มต้น ( ใน$homeตัวแปรตามที่ระบุไว้โดย @JdeBP )

หากคุณยกเลิกการตั้งค่าก่อนเริ่มต้นcshคุณจะเห็นสิ่งต่อไปนี้:

$ (unset HOME; csh -c cd)
cd: No home directory.

สำหรับbash(และกระสุนที่คล้ายบอร์นส่วนใหญ่) ฉันเห็นพฤติกรรมที่แตกต่างจากของคุณ

bash-4.4$ unset HOME; cd
bash: cd: HOME not set

เนื้อหาของ$HOMEตัวแปร initialised โดยกระบวนการเข้าสู่ระบบบนพื้นฐานของข้อมูลที่เก็บไว้ในฐานข้อมูลผู้ใช้กับผู้ใช้ของคุณชื่อ

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

ดังนั้นเมื่อ$HOMEหมดไปแล้วจะไม่มีวิธีที่เชื่อถือได้ในการนำกลับคืนมา

การเคียวรีฐานข้อมูลผู้ใช้ (ด้วยgetpwxxx()API มาตรฐาน) สำหรับโฮมไดเร็กทอรีของผู้ใช้แรกที่มี uid เดียวกับที่รันเชลล์จะเป็นการประมาณเท่านั้น (ไม่ต้องพูดถึงความจริงที่ว่าฐานข้อมูลผู้ใช้สามารถเปลี่ยนแปลงได้ (หรือโฮม ไดเรกทอรีที่ถูกกำหนดเป็นค่าครั้งเดียว) นับตั้งแต่เซสชั่นการเข้าสู่ระบบเริ่มต้นขึ้น)

zsh เป็นเปลือกเดียวที่ฉันรู้ว่าทำอย่างนั้น:

$ env -u HOME ltrace -e getpw\* zsh -c 'cd && pwd'
zsh->getpwuid(1000, 0x496feb, 114, 0x7f9599004697)      = 0x7f95992fddc0
/home/chazelas
+++ exited (status 0) +++

กระสุนอื่น ๆ ทั้งหมดที่ฉันพยายามบ่นเกี่ยวกับการยกเลิกการตั้งค่าหน้าแรกนั้นหรือใช้/เป็นค่าเริ่มต้นที่บ้าน

แต่พฤติกรรมที่แตกต่างคือfish's ซึ่งดูเหมือนว่าจะสอบถามฐานข้อมูลสำหรับชื่อผู้ใช้ที่เก็บใน$USERถ้ามีหรือทำgetpwuid()ถ้าไม่:

$ env -u HOME USER=bin ltrace -e getpw\* fish -c 'cd;pwd'
fish->getpwnam("bin")  = 0x7fd2beba3d80
fish: Unable to create a configuration directory for fish. Your personal settings will not be saved. Please set the $XDG_CONFIG_HOME variable to a directory
where the current user has write access.
fish: Unable to create a configuration directory for fish. Your personal settings will not be saved. Please set the $XDG_CONFIG_HOME variable to a directory
where the current user has write access.
--- SIGCHLD (Child exited) ---
/bin
+++ exited (status 0) +++


$ env -u HOME -u USER ltrace -e getpw\* fish -c 'cd;pwd'
fish->getpwuid(1000, 0x7f529eb4fb28, 0x12d8790, 0x7f529e858697) = 0x7f529eb51dc0
fish->getpwnam("chazelas")                                      = 0x7f529eb51d80
--- SIGCHLD (Child exited) ---
--- SIGCHLD (Child exited) ---
/home/chazelas
+++ exited (status 0) +++

SEGV เมื่อไม่มีผู้ใช้ ( https://github.com/fish-shell/fish-shell/issues/3599 ):

$ env -u HOME USER=foo fish -c ''
zsh: segmentation fault  env -u HOME USER=foo fish -c ''

2
ฉันคิดว่าเราสามารถรายงานปัญหานี้ได้! btw คำตอบที่ดีมากขอบคุณ!
LotoLo

1
@LotoLo ใช่ฉันยุ่งอยู่กับการสร้างfishหัว dev ของคอมไพล์เพื่อดูว่ามีบั๊กอยู่ด้วยหรือไม่ แก้ไข ใช่แล้ว.
Stéphane Chazelas

ตอนนี้ฉันอยากรู้อยากเห็น: ตัวแปรสภาพแวดล้อมใดที่ทำให้เชลล์ใช้งานง่ายที่สุดหากไม่ได้ตั้งค่า PATH? TERM? USER?
user1024

มีเส้นแปลก ๆ ที่นี่: "จะเป็นการประมาณเท่านั้น ... " วงเล็บไม่เรียงกันในย่อหน้านั้นด้วย มันควรจะเป็นอะไร
muru

1
@muru Querying the user database... would only be...ไม่ชัดเจนอย่างแน่นอน
edc65

6

แล้วเชลล์รู้ได้อย่างไรว่าบ้านของฉัน / other_user อยู่ที่ไหน?

มันไม่ได้ คุณเพียงแค่ทำการทดสอบไม่ถูกต้อง ดังที่คุณเห็นได้จากคู่มือ C เชลล์cdคำสั่งจะเปลี่ยนเป็นค่าของhomeตัวแปรหากระบุโดยไม่มีอาร์กิวเมนต์ หากตัวแปรนี้ไม่มีการตั้งค่าจะไม่ทราบว่าจะเปลี่ยนไดเรกทอรีไปที่ใดและพิมพ์ข้อผิดพลาด:

เครื่อง: ~> set home = /
เครื่อง: / home / user> cd
เครื่อง: ~> unset home
เครื่อง: /> cd
cd: ไม่มีโฮมไดเร็กตอรี่
เครื่อง: /> 

คุณยกเลิกการตั้งค่าตัวแปรที่ไม่ถูกต้อง ไม่ใช่HOMEตัวแปรสภาพแวดล้อมมันเป็นhomeตัวแปรภายในของ C เชลล์ (เริ่มต้นจากค่าของอดีตเมื่อเชลล์เริ่มต้นขึ้น แต่ไม่เช่นนั้นจะเป็นตัวแปรอิสระที่อยู่ด้านขวา)


ไม่อยู่ใน csh (อย่างน้อยในเวอร์ชั่นของฉัน: "tcsh 6.18.01 (Astron) 2012-02-14 (x86_64-apple-darwin)") มันเป็นตัวแปร HOME ซึ่งเป็นค่าของบ้าน แต่ตามที่ @Stephane Chazelas กล่าวว่าฉันต้องยกเลิกการตั้งค่าตัวแปรก่อนที่จะเปิดตัวเชลล์เนื่องจากมันจะตั้งค่า HOME เมื่อเริ่มต้น
LotoLo

ด้านบนคือ C เชลล์ซึ่งฉันใช้กับเครื่อง OpenBSD ที่มีประโยชน์และแสดงพฤติกรรมของมัน มันไม่ใช่แม้แต่กระสุน TENEX C (แม้ว่ามันจะทำงานเหมือนกัน)
JdeBP

ใช่ฉันเห็นมัน ... ฉันพิมพ์cshแต่เห็นได้ชัดว่ามันเป็นนามแฝงถึงtcsh
LotoLo

0

ระบบตั้งค่าตัวแปร HOME ในเวลาที่ล็อกอินเป็นชื่อพา ธ ของโฮมไดเร็กทอรีของผู้ใช้ มันถูกกำหนดโดย

  • gdm, kdm หรือ xdm สำหรับเซสชันกราฟิก
  • ล็อกอินบนเซสชันคอนโซล telnet และ rlogin
  • sshd สำหรับการเชื่อมต่อ SSH

คุณสามารถเปลี่ยนค่าของมัน แต่ให้ความสนใจเพราะ. bashrc, .profile, .xinitrc ฯลฯ จะไม่สามารถอ่านได้หากพวกเขาไม่อยู่ในโฮมไดเร็กตอรี่


แต่ฉันสามารถยกเลิกได้ ($ HOME) ... ใช่ไหม และจะทราบได้อย่างไรว่าบ้านของผู้ใช้รายอื่นอยู่ที่ไหน
LotoLo

1
คุณสามารถอัปเดตโดยใช้usermod -d HOME_DIRคำสั่งเมื่อสร้าง usre ใหม่ บ้านเริ่มต้นคือ / home / $ ชื่อผู้ใช้และมันถูกกำหนดโดยโปรแกรมเข้าสู่ระบบ
Dababi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.