ความแตกต่างระหว่าง 'cd' และ 'cd ~'


10

ฉันสงสัยว่าถ้าซีดีเพียงอย่างเดียวส่งฉันไปที่โฟลเดอร์บ้านและcd ~ทำแบบเดียวกันทำไม ~ ถูกเพิ่มเข้ามาตั้งแต่แรก?

เป็นสิ่งที่เฉพาะเจาะจงกับ BASH หรือว่าพวกเขาจะมีพฤติกรรมที่แตกต่างในเชลล์อื่นหรือไม่?


2
ไม่ซ้ำกันแน่นอน คำถามที่ถูกถามเกี่ยวกับcd ~VS VScd $HOME cd ~not-tanduคำถามนี้เป็นคำถามที่ถามเกี่ยวกับVScd cd ~

คำตอบ:


17

~สามารถใช้สำหรับการมากกว่าเพียงแค่ว่า คำสั่งใด ๆ สามารถทำกำไรจากการมีทางลัดไปยังโฟลเดอร์บ้าน ดังนั้นจึงไม่จำเป็นถ้าคุณต้องการที่จะ cd เข้าไปในบ้านของคุณ แต่สิ่งที่เกี่ยวกับ~/.config?

$ cd ~/.config

มิฉะนั้นคุณจะต้องเขียนเส้นทางบ้านใช้$HOMEvar หรือทำสองcds นอกจากนี้สำหรับการคัดลอกหรือย้ายไฟล์:

$ cp ~/downloads/some-file some/path/

เนื่องจากไฟล์ส่วนใหญ่อยู่ในบ้านคุณจึงควรมีทางลัดอยู่เสมอ


สวัสดี ahilsend คำถามของฉันคือการมุ่งเน้นไปที่ทำไมทั้งสองวิธี ฉันรู้แล้วเกี่ยวกับ ~ โดยใช้ตัวแปร $ HOME แต่ด้วยความคิดนี้ทำไม "ซีดี" เพียงอย่างเดียวก็ส่งฉันกลับบ้านด้วย ทำไม 2 วิธีเพื่อจุดประสงค์เดียวกัน?
Luis Alvarado

4
@CYREX ฉันเดาว่าจะบันทึกการพิมพ์สำหรับกรณีทั่วไปที่ต้องการย้ายไปยังไดเรกทอรีบ้านของคุณ
CVn

1
การใช้งานอื่น ๆ ของสิ่งที่~ต้องทำcd ~user/downloadเพื่อไปที่ไดเรกทอรีดาวน์โหลดของผู้ใช้
ott--

5

การทำcd นั้นเป็นการเรียกcdโดยไม่มีข้อโต้แย้งและตามcdพฤติกรรม "... หากไม่ได้ระบุค่า dir ค่าของตัวแปร HOME shell จะเป็นค่าเริ่มต้น" (จากคู่มือทุบตี ) ในทางตรงกันข้ามcd ~คือเมื่อคุณจัดหาอาร์กิวเมนต์cdคำสั่งที่เกิดขึ้นจะเป็น~และเปลือกจะดำเนินการตัวหนอนขยายตัว เท่าที่จะกลับไปที่โฮมไดเร็กตอรี่ของผู้ใช้ - ไม่มีความแตกต่าง ในทั้งสองกรณีHOMEตัวแปรสภาพแวดล้อมจะถูกสอบถาม:

$ env 'HOME=/usr' bash -c 'cd;pwd; cd ~;pwd'                                      
/usr
/usr

cd $HOMEได้อย่างมีประสิทธิภาพนอกจากนี้ยังมีความแตกต่างจากการไม่มี อย่างไรก็ตามในขณะที่cdจะทำอย่างใดอย่างหนึ่งเท่านั้นตัวหนอนสามารถใช้ในการขยายตัวอื่น ๆ เช่น~+ไดเรกทอรีการทำงานปัจจุบัน

อย่างไรก็ตามน่าสนใจพอที่เราสามารถunset HOMEทำลายได้cdแต่~จะยังคงทำงาน:

$ bash -c 'cd /usr;unset HOME;cd;pwd;cd ~;pwd'                                    
bash: line 0: cd: HOME not set
/usr
/home/xieerqi

ทำไม อีกครั้งตอบในคู่มือ:

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

ขอให้สังเกตว่าการตั้งค่าจะแตกต่างกันซึ่งทำให้ตัวแปรว่างเปล่าHOME=และมีผล เอกสารอธิบายถึงตัวแปรที่ไม่ได้ตั้งค่าโดยเฉพาะ การทำให้ตัวแปรเท่ากับสตริงว่างมีผลตรงข้ามกับสิ่งที่เราคาดหวัง:

bash-4.3$ env 'HOME=' bash -c 'cd /usr;set|grep "^HOME"; stat -c "%F" ~;cd;pwd'
HOME=
stat: cannot stat '': No such file or directory
/usr

ที่นี่คุณจะเห็นว่าการทำให้HOMEสตริงว่างแบ่งทั้งตัวหนอนและcdพฤติกรรม


Tilde และ$HOMEมีความแตกต่างและเหตุผลที่แตกต่างกันสำหรับการดำรงอยู่ $HOMEเป็นตัวแปรเชลล์ซึ่งบังเอิญเกิดขึ้นร่วมกับหนึ่งในตัวแปรสภาพแวดล้อม - และที่มีอยู่ในโปรแกรมทั้งหมด ใน C คุณจะใช้environ()ในการเข้าถึง ในทางตรงกันข้ามtildeเป็นไวยากรณ์เฉพาะเชลล์ที่ดำเนินการขยายตัวหนอนแม้ว่าคุณสามารถใช้wordexp()ฟังก์ชั่นในการดำเนินการขยายตัวเหมือนเชลล์ ( อ้างอิง ) ใน C เช่นกัน

เหตุผลที่~ตัวแทนHOMEได้รับการตอบในคำถามนี้ : ตัวละครตัวหนอนแบ่งปันคีย์เดียวกันกับHOMEเทอร์มินัล Lear-Siegler ADM-3A HOMEตรงกันข้ามเป็นตัวแปรสภาพแวดล้อมที่มีความหมายเชิงสัญลักษณ์ล้วนๆและไม่มีการแสดงออกทางกายภาพ

นอกจากนี้ความจริงที่ว่าHOMEเป็นตัวแปรสภาพแวดล้อมทำให้เราสามารถยกเลิกการตั้งค่าได้เนื่องจากในขณะที่เราไม่สามารถตั้งค่า~เป็นอย่างอื่นได้ด้วยวิธีการง่ายๆ

# cd ~ will still work, because ~ is blank, so it's same as just cd
$ bash -c 'unset HOME; echo $HOME; cd ~;pwd'                           

/home/xieerqi
$ env 'HOME=' bash -c 'echo $HOME; cd ~;pwd'                                

/home/xieerqi

สังเกตุเห็นบรรทัดว่างที่แรกechoส่งออกตัวแปร unset และข้อเท็จจริงที่ว่า ในทางตรงกันข้ามเราไม่สามารถทำสิ่งนี้กับตัวหนอนได้:

$ bash -c '~=; cd ~;pwd'                                                    
bash: ~=: command not found
/home/xieerqi
$ bash -c '~=$'\0'; cd ~;pwd'                                               
bash: ~=bash: command not found
/home/xieerqi
$ bash -c 'unset ~; cd ~;pwd'                                               
bash: line 0: unset: `/home/xieerqi': not a valid identifier
/home/xieerqi

อย่างไรก็ตามการเปลี่ยนแปลงHOMEจะมีผลกับ~:

$ env 'HOME=' bash -c 'echo $HOME; stat ~;'                                 

stat: cannot stat '': No such file or directory

นอกจากนี้เนื่องจาก~ทำงานเป็นอักขระการขยายเราสามารถทำสิ่งนี้เพื่อแสดงไดเรกทอรีการทำงานปัจจุบัน:

$ bash -c 'cd /etc/;stat -c "%n" ~+'                                        
/etc

โดยที่ถ้าเราต้องการทำสิ่งนั้นผ่านตัวแปรสภาพแวดล้อมเราต้องการPWDและHOMEยังคงเหมือนเดิมหรือถ้าคุณทำสิ่งต่าง ๆ เช่นecho $HOME+- นั่นเป็นเพียงการต่อสตริง / ตัวแปรเท่านั้น แต่~+นำข้อมูลออกมาจากตัวแปรสภาพแวดล้อมอีกครั้ง:

$ bash -c 'cd /etc/;PWD="/usr";stat -c "%n" ~+'                             
/usr

หมายเหตุ : ตัว~+และ~-การขยายงานในแต่ไม่ได้อยู่ในkshdash


ในการตอบคำถามเฉพาะของคุณ:

เป็นสิ่งที่เฉพาะเจาะจงกับ BASH หรือว่าพวกเขาจะมีพฤติกรรมที่แตกต่างในเชลล์อื่นหรือไม่?

ไม่สิ่งนี้ควรเป็นพฤติกรรมที่สอดคล้องกัน ksh, dashและcsh- ทั้งหมดประพฤติเช่นเดียวกันกับหรือcdcd ~

ทำไม ~ ถูกเพิ่มเข้ามาในตอนแรก?

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


0

ไม่ว่าคุณจะมีหลายระดับโฟลเดอร์ด้านบนหรือด้านล่าง$HOMEคำสั่งcdและcd ~ทำสิ่งเดียวกันและไม่แตกต่างกัน - มันจะส่งคุณกลับไปยังไดเรกทอรีหน้าแรกของคุณ

อย่างไรก็ตามเมื่อคุณมี 1 หรือโฟลเดอร์มากขึ้นในระดับที่เหนือบ้านและคุณต้องการที่จะไปโดยตรงไปยังไดเรกทอรีย่อย 1 หรือระดับโฟลเดอร์เพิ่มเติมด้านล่าง$HOME, ตัวหนอน ( ~) มาในสะดวกโดยคุณประหยัดการกดแป้นพิมพ์เมื่อนำมาใช้เพื่อทดแทนข้อความที่จำเป็นในการดู ไป$HOMEเมื่อพิมพ์cdคำสั่ง ตัวอย่างเช่น

/$ cd    # (or cd ~)
~$ pwd
/home/foo
~$ dir
bar bar2 bar3
~$ cd ..
/$ cd ..
/$ pwd
/
/$ cd /bar3
bash: cd: /bar3: no such file or directory
/$ cd ~/bar3    # (instead of "cd /home/foo/bar3")
~/bar3$ pwd
/home/foo/bar3

0

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


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