ซีดีหรือไม่ มีการใช้งาน?


102

หนึ่งในบทเรียนที่ฉันได้รับการกล่าวสั้น ๆ ว่าcd .ไม่มีประโยชน์ เมื่อพยายามทำซ้ำปัญหาที่แสดงโดย OP ในการเรียกลิงก์สัญลักษณ์ซ้ำ - อะไรทำให้ "รีเซ็ต"? ผมก็พยายามcd .ซึ่งแสดงให้เห็นว่า OP ผลเช่นเดียวกันอธิบาย (การเจริญเติบโต$PWDตัวแปร) cd -Pซึ่งสามารถนำมาโต้กับ

นี้ทำให้ฉันสงสัยจะมีกรณีใดที่หนึ่งในความเป็นจริงจะต้องการใช้cd . ?


20
ฉันมี. zshrc แบบกำหนดเองที่เรียกใช้การตรวจสอบต่าง ๆ ในไดเรกทอรีเมื่อสลับไดเรกทอรีตัวอย่างเช่นหนึ่งในการตรวจสอบคือการเปิดใช้งาน / ปิดใช้งาน virtualenv ที่ตรงกันโดยอัตโนมัติเมื่อย้ายไดเรกทอรี บางครั้งฉันอาจเริ่มเชลล์ใหม่หรืออะไรก็ตามและเช็คเหล่านั้นไม่ทำงานและฉันมักจะใช้cd .เพื่อทริกเกอร์เช็คเหล่านั้นเพราะมันสั้นและง่าย แม้ว่าฉันคิดว่าคุณตั้งใจจะให้เป็นคำถามสำหรับสภาพแวดล้อมของวานิลลา
Lie Ryan

29
นอกจากผลกระทบ (ชัดเจน) $PWDแล้วcd .ยังเปลี่ยน$OLDPWDเป็นไดเรกทอรีปัจจุบัน ฉันมี (ในปัจจุบัน) ไม่ทราบว่าทำไมสิ่งนี้อาจมีประโยชน์ แต่เพื่อความสมบูรณ์ ...
Andreas Wiese

5
ฉันไม่คิดว่าฉันเคยต้องการcd .แม้ว่าจะเห็นคำตอบด้านล่างฉันอาจจะมีในอนาคต แต่ฉันมีโอกาสที่จะใช้pushd .เมื่อฉันต้องการที่จะสามารถpopdกลับไปยังไดเรกทอรีนี้ในภายหลัง เช่นเมื่อทำงานสร้างสคริปต์ที่ไม่configure, cd output...และmakeและเมื่อมันทำฉันจะต้องการที่จะกลับไปยังไดเรกทอรีเดิม แทนที่จะเก็บรักษา buildscript ของตัวเองที่แตกต่างจากที่คนอื่นคาดหวังฉันก็แค่เรียกใช้pushd .; ./BuildScriptName.sh; popdและนี่ก็ทำให้ฉันมีอิสระที่จะไม่ได้เป็นpopdบางครั้งแล้วpopdก็แทนในภายหลัง
3D1T0R

5
ไม่ต้องพูดถึงแน่นอนว่า '.' และ '.. ' ไม่ได้ถูกนำไปใช้ในคำสั่ง cd ดังนั้นจึงไม่มีใครกำหนดให้ใช้คุณลักษณะเฉพาะนั้นมันเป็นเพียงการรวมกันของสิ่งต่าง ๆ ที่ไม่มีจุดประสงค์ที่แท้จริง
เดวิดเอส

1
@ruakh Nope โปรแกรมภายนอกไม่ควรส่งผลกระทบต่อสภาพแวดล้อมการทำงานของเชลล์ ส่วนใหญ่เป็นการปฏิบัติตาม POSIX ซึ่งต้องการให้ยูทิลิตี้บางอย่างอยู่นอกเชลล์และประเมินสถานะทางออกของคำสั่งภายนอก คุณสามารถอ่านเกี่ยวกับวัตถุประสงค์ของ/bin/cdที่นี่unix.stackexchange.com/q/50058/85039
Sergiy Kolodyazhnyy

คำตอบ:


158

ฉันคิดว่านี่เป็นปัญหาที่เกิดขึ้น cd .อาจไม่ใช่สิ่งที่คนจะทำงานด้วยตนเองตามปกติในสิ่งต่าง ๆ แต่แน่นอนว่าเป็นสิ่งที่สามารถเกิดขึ้นในการดำเนินการทางโปรแกรม (คิดว่าสถานการณ์ใด ๆ ที่คุณอาจcdไปยังไดเรกทอรีที่มีไฟล์ที่มีเส้นทางที่ผู้ใช้กำหนด ) ดังนั้นจึงไม่จำเป็นต้องใช้งานเฉพาะ: ตราบใดที่มันเติมเต็มความหมายตามปกติของcd <some-path>มันก็มีประโยชน์


12
ตกลง .ควรถือว่าเป็นเส้นทางที่ถูกต้องระบุโดยcdไวยากรณ์ได้ดี
Sergiy Kolodyazhnyy

18
คุณสามารถเพิ่มตัวอย่างต่อไปนี้: IFS= read Dir; do cd "$Dir"; do_something; done < <(find . -type d)ลูปเช่นในขณะที่ ในช่วงของการค้นหาผลิต.เป็นเส้นทางเพื่อให้คำสั่งขยายcd "$Dir" cd .ดังนั้นในสคริปต์มันมีประโยชน์อย่างสมบูรณ์
rexkogitans

5
ตัวอย่างเช่นสคริปต์ทำงานจริงcd ${path_to_directory}แต่ในบางจุดมันกลับกลายเป็นว่าไดเรกทอรีเป็นไดเรกทอรีปัจจุบันและpath_to_directory = .ดังนั้นคุณจะต้องcd .ทำงานในกรณีที่
Demis

4
ในคำอื่น ๆ ยูทิลิตี้ที่อยู่ในความจริงที่ว่ามันทำให้รหัสพิเศษ ( ifตรวจสอบและelseข้อชนิดของท่อพิเศษใด ๆ ) ที่ไม่จำเป็น
jpmc26

2
ดังนั้นจึงมีประโยชน์ในแง่ที่ว่า x + 0 หรือ x * 1 มีประโยชน์ - การดำเนินการเฉพาะไม่เป็นประโยชน์ต่อ se แต่หมายความว่าคุณสามารถจัดการ 0 และ 1 เหมือนกับค่าอื่น ๆ โดยไม่ต้องปฏิบัติต่อมันเป็น กรณีพิเศษ
user32929

127

เส้นทางของไดเรกทอรีอาจมีการเปลี่ยนแปลงนับตั้งแต่คำสั่งสุดท้ายถูกดำเนินการและไม่มีcd .เชลล์ bash และ ksh93 จะขึ้นอยู่กับไดเรกทอรีการทำงานเชิงตรรกะที่อธิบายไว้ในโพสต์ที่เชื่อมโยงในคำถามดังนั้นการโทรcd .ที่ทำให้ปัญหาเชลล์getcwd()syscall ของคุณ เส้นทางปัจจุบันยังคงใช้ได้

ขั้นตอนในการทำซ้ำในทุบตี:

  1. ในปัญหาแท็บเทอร์มินัล mkdir ./dir_no_1; cd ./dir_no_1
  2. ในปัญหาแท็บเทอร์มินัลอื่น mv dir_no_1 dir_no_2
  3. ในประเด็นแท็บขั้วครั้งแรกและecho $PWD pwdขอให้สังเกตว่าไดเรกทอรีได้ถูกเปลี่ยนชื่อภายนอก สภาพแวดล้อมของเชลล์ไม่ได้รับการอัพเดต
  4. cd .; pwd; echo $PWDปัญหา แจ้งให้ทราบค่าที่ได้รับการปรับปรุง

ksh93 อย่างไรก็ตามไม่อัพเดตข้อมูลสภาพแวดล้อมดังนั้นcd .ในความเป็นจริง ksh93 อาจไร้ประโยชน์ ใน/bin/dashUbuntu และระบบที่ใช้เดเบียนอื่น ๆcd .ส่งคืนdash: 3: cd: can't cd to .ข้อผิดพลาด แต่ใช้cd -P .งานได้ (ต่างจาก ksh93)


22
สิ่งที่ควรรู้: ฉันจะเพิ่มเข้าไปในรายการข้อมูลที่ไร้ประโยชน์ของฉัน ^^)
jayooin

12
@jayooin ดีใจที่ฉันสามารถมีส่วนร่วมในรายการ;)
Sergiy Kolodyazhnyy

8
ฉันคิดว่าคุณสามารถทำmv ../dir_no_1 ../dir_no_2ในแบบเดียวกันขั้ว / ทุบตี
ctrl-alt-delor

3
@ ctrl-alt-delor ยืนยันทำงาน :)
Sergiy Kolodyazhnyy

1
@ymbirtt ในเชลล์ส่วนใหญ่แล้วpwdในความเป็นจริงแล้วตัวบิวด์อินอย่างไรก็ตามการเรียกใช้/bin/pwdไม่มีผลกระทบต่อสภาพแวดล้อมของเชลล์ - ยูทิลิตี้ภายนอกโดยทั่วไปจะไม่ส่งผลกระทบต่อสภาพแวดล้อมของเชลล์ เหตุผลที่ว่าทำไม/bin/cdและ/bin/pwdมีอยู่เพื่อ POSIX สอดคล้องเหนือสิ่งอื่นใด มีการอภิปรายที่ดีเกี่ยวกับแผ่นซีดีภายนอกบางอย่างที่อาจใช้กับ/bin/pwdเช่นกัน
Sergiy Kolodyazhnyy

55

กรณีการใช้อีกกรณีหนึ่งcd .คือเมื่อไดเรกทอรีที่คุณอยู่นั้นถูกลบไปแล้วและทำอีกครั้ง ลองพิจารณาสิ่งต่อไปนี้ -

  1. สร้างไดเรกทอรี temp
  2. cd temp จากนั้นทำ ls
  3. เปิดเทอร์มินัลอื่นแล้วลบจากนั้นสร้างไดเรกทอรีใหม่ temp
  4. กลับจากเทอร์มินัลแรกลองทำ ls ซึ่งจะส่งผลให้เกิดข้อผิดพลาด -ls: cannot open directory .: Stale file handle
  5. cd . แล้วทำ ls ได้ผลดี

3
มันไม่ได้ผลเสมอไป ตัวอย่างเช่นในแดชคุณจะได้รับ: cd: can't cd to .ตอนนี้ฉันดูแล้วนี่ถูกกล่าวถึงแล้วในคำตอบของ Sergiy (การย้ายการลบ / สร้างใหม่ - โดยพื้นฐานแล้วเหมือนกัน: ไดเรกทอรีที่คุณอยู่ไม่ได้อยู่ในสภาพเดิม เส้นทาง)
Olorin

12
ฉันใช้สิ่งนี้ทดสอบระยะไกล deploys มาก ไดเรกทอรีที่ฉันอยู่จะถูกลบจากนั้นสร้างขึ้นใหม่โดยระบบอัตโนมัติและฉันจะต้องออกcd .เพื่อย้ายไปยังไดเรกทอรีใหม่ที่มีชื่อเดียวกัน
HP Williams

2
ฉันใช้cd .ตลอดเวลาเมื่อฉันมีเชลล์ที่มีไดเร็กทอรีการทำงานปัจจุบันถูกเมาท์ด้วย sshfs แต่เซสชัน ssh ถูกปิดและเปิดใหม่
jamesdlin

4
ในกรณีเช่นนี้ฉันจะทำ "cd $ PWD" ตัวแปรอื่นอาจใช้งานได้ แต่สิ่งนี้แสดงเจตนาชัดเจน: แยกสิ่งที่ควรจะเป็นเส้นทางปัจจุบันของฉัน (เช่นอ่านเนื้อหาของPWDตัวแปรสภาพแวดล้อม) จากนั้นเดินลำดับชั้นของระบบแฟ้มจากรากลงสู่ไดเรกทอรีที่เข้าถึงได้ผ่านทาง เส้นทางนั้นไม่ว่าจะเป็นไดเรกทอรีเดียวกันจริงหรือไม่ ตรงกับกรณีการใช้งานในคำตอบนี้
Stéphane Gourichon

3
ฉันประหลาดใจจริงๆตกใจแม้กระทั่งที่cd .ทำงานเมื่อไดเรกทอรีถูกยกเลิกการเชื่อมโยงและสร้างไดเรกทอรีใหม่ที่แตกต่างกันที่เส้นทางของระบบไฟล์เดียวกัน ไดเรกทอรีการทำงานปัจจุบันได้ถูกยกเลิกการเชื่อมโยงและสันนิษฐานว่าเป็นส่วนหนึ่งของไดเรกทอรีดังกล่าวไม่มีรายการ.หรืออีกต่อไป..และแม้ว่าจะเป็นเช่น.นั้น ดูเหมือนว่าเชลล์หรือเคอร์เนลกำลังประมวลผลคำสั่ง cd ตามชื่อพา ธ ของไดเร็กทอรีแทนที่จะเป็นการเข้าถึง.รายการ ทุกคนสามารถยืนยันพฤติกรรมนั้นได้หรือไม่
Adrian Pronk

36

คุณสามารถล้าง$OLDPWDข้อมูลได้อย่างรวดเร็วcd .หากมีกรณีที่คุณไม่ต้องการให้ชี้ไปที่ใดก็ได้ "น่าสนใจ" cd -นอกจากนี้ยังจะส่งผลกระทบต่อ


16

โดยทางโปรแกรมแล้วมันมีประโยชน์ในฐานะที่ไม่ใช้งาน พิจารณาพา ธ ที่ได้จากอินพุตภายนอก

read -p "Path to file: " p
dirn=$(dirname "$p")
file=$(basename "$p")
echo "dirn=$dirn, file=$file"
cd "$dirn"
ls -ld "$file"

ด้วยพา ธ เช่น "fred.txt" ไดเรกทอรีจะกลายเป็นสิ่งที่.นำไปสู่cd .


1
มันมีประโยชน์ที่จะไม่โยนข้อผิดพลาดหากคุณอยู่ในไดเรกทอรีที่คุณใช้งานอยู่ แต่ฉันจะไม่บอกว่ามันมีประโยชน์ในฐานะที่ไม่ใช้งาน
Captain Man

2
@CaptainMan ไม่ได้ทิ้งข้อผิดพลาดหากคุณอยู่ในไดเรกทอรีแล้ว (ไม่ได้ผล) - dirnameคำสั่งสร้าง.ที่จำเป็นเพื่อหลีกเลี่ยงรหัสทำลายที่คาดว่าจะสามารถที่จะแยกเส้นทาง
roaima

15

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


1
จะไม่ขึ้นอยู่กับประเภทของอุปกรณ์วิธีการเข้าถึงระบบไฟล์ OS และ c
gidds

ระบบปฏิบัติการอาจจะ มันไม่น่าเป็นไปได้ที่ระบบไฟล์จะมีความเกี่ยวข้องตราบใดที่เคอร์เนลสามารถหาวิธีถอนการติดตั้งในขณะที่กำลังใช้งานอยู่ ในกรณีใด ๆ คำสั่งมีการใช้งานในสถานการณ์ที่ถูกต้อง
23013

11

โปรดทราบว่า "." เป็นวิธีที่เหมาะสมในการระบุชื่อไฟล์ที่เปิดเป็นไดเรกทอรีการทำงานปัจจุบันของกระบวนการใด ๆ (รวมถึงกระบวนการเชลล์ของหลักสูตร) ​​และ "." เป็นชื่อที่ถูกต้องของไฟล์ในทุก ๆ ไดเรกทอรีรวมถึงไดเรกทอรีการทำงานปัจจุบัน ชื่อ.อาจไม่ใช่ชื่อที่ถูกต้องสำหรับไฟล์สำหรับอินสแตนซ์ที่กำหนดของกระบวนการถ้าพูดว่าไดเรกทอรีการทำงานปัจจุบันถูกลบออก (หรือหายไป "ไม่ดี" เช่นตัวจัดการ NFS เก่า) แต่เป็นชื่อที่ถูกต้อง ของไฟล์ที่รับประกันว่าจะมีอยู่ในทุกไดเรกทอรีที่ถูกต้อง

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

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

อย่างน้อยบางเชลล์ที่ฉันรู้จัก ( /bin/shบน FreeBSD และ NetBSD) จะแปลงcd ""เป็นcd .ซึ่งสามารถอธิบายคุณสมบัติเพื่อสนับสนุนการใช้โดยทางโปรแกรมในเชลล์สคริปต์ซึ่งตัวแปรอาจใช้เป็นพารามิเตอร์ (เช่นการแปลงการแทนที่ตัวแปรว่างเปล่าเป็น " ไม่ต้องทำสิ่งใด "ผลลัพธ์) ถึงแม้ว่า FreeBSD จะส่งประวัติว่าการเปลี่ยนแปลงนั้นเกิดขึ้นโดยตรงเนื่องจากการเพิ่มการสนับสนุน POSIX เพื่อป้องกันความล้มเหลวchdir("")ซึ่งเอกสาร POSIX ต้องล้มเหลว

บางหอยอื่น ๆ ที่จะเข้ามาแทนที่.กับสิ่งที่พวกเขาได้เก็บไว้เป็นชื่อพา ธ ที่มีคุณสมบัติครบถ้วนที่จะไดเรกทอรีที่ทำงานปัจจุบันของพวกเขาและทำให้สำหรับพวกเขานี้อาจช่วยให้สำหรับพฤติกรรมที่กล่าวถึงในคำตอบของ Sahil Agarwal


4

ฉันใช้คำสั่งนี้ในวันนี้เมื่อฉันรีบูตสาขาที่ฉันทำงานใน Git จากภายในไดเรกทอรีที่สร้างขึ้นครั้งแรกในสาขาเดียวกันนั้น rebase ไปได้ดี แต่หลังจากนั้นgit statusโยนข้อผิดพลาด หลังจากcd .ทุกอย่างเป็นปกติ

(ฉันทำงานใน MobaXterm บน Windows โดยบังเอิญในกรณีที่คุณพยายามทำซ้ำสิ่งนี้อาจไม่เกิดขึ้นกับระบบอื่น)


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


หลังจากอ่านคำตอบที่ยอดเยี่ยมนี้จาก Stephane Chazelas:

ตอนนี้ผมเข้าใจว่ากรณีการใช้งานของฉันข้างต้นทำงานเพียงเพราะฉันใช้bashซึ่งเทียบเท่ากับcd . cd "$PWD"ฉันขอแนะนำให้อ่านคำตอบที่เชื่อมโยง


1

ฉันใช้cd .เพื่อเรียกใช้สิ่งที่ฉันโอเวอร์โหลดcdด้วยbashฟังก์ชั่นอีกครั้ง

จากฉัน~/.bashrc:

# from the "xttitle(1)" man page - put info in window title
update_title()
{
    [[ $TERM = xterm ]] || [[ $TERM = xterm-color ]]  && xttitle "[$$] ${USER}@${HOSTNAME}:$PWD"
}

cd()
{
    [[ -z "$*" ]] && builtin cd $HOME
    [[ -n "$*" ]] && builtin cd "$*"
    update_title
}

0

แก้ไข:นี้ได้รับการแนะนำโดยSahilก่อนหน้านี้

สิ่งนี้มีประโยชน์หากคุณอยู่ในโฟลเดอร์ที่ถูกลบและสร้างใหม่โดยกระบวนการอื่น ตัวอย่างเช่นสมมติว่าทั้งสองเทอร์มินัลเซสชัน$1และ$2:

$1 mkdir d
$1 cd d
$1 touch f

$2 rm -rf /path/to/d # delete the folder where $1 is in ...
$2 mkdir /path/to/d # ... and recreate it

$1 touch g # cannot create file g because current dir doesn't exist anymore
touch: cannot touch ‘g’: Stale file handle
$1 cd . # go to the newly created dir (same path)
$1 touch g # works fine now

ฉันไม่แน่ใจว่าที่จริง (OS, SHELL, ... ?) ที่เป็นต้นเหตุของพฤติกรรมนี้หรือไม่


คำตอบอื่น ๆ ได้ถูกกล่าวถึงแล้วนี้
Kusalananda

-8

ไม่มันไม่มีเหตุผล ในการเขียนสคริปต์มันไม่ได้ทำอะไรเลย


2
ทั้งนี้ขึ้นอยู่กับเปลือกก็จะรีเซ็ต$PWDและมันอาจจะเรียกฟังก์ชั่นอื่น ๆ เปลือกถ้าผู้ใช้ได้ให้ตัวเองฟังก์ชั่นหรือนามแฝงเกินที่สร้างขึ้นในcd cdนอกจากนี้ยังจะตรวจสอบว่าไดเรกทอรีปัจจุบันยังคงถูกต้องและการใช้งานปัจจุบันมีสิทธิ์ที่จะอยู่ที่นั่น
Kusalananda

1) แน่นอนว่าเราไม่ได้พูดถึงนามแฝงที่กำหนดเองที่เป็นไปได้ของ "cd" แต่สร้างมาตรฐาน 2) วิธีการใช้งานปัจจุบันสามารถอยู่ที่นั่นได้อย่างไรหากไม่มีสิทธิ์? เพื่อให้ง่ายฉันแค่บอกว่าในโลกแห่งความจริงไม่มีเหตุผลที่จะใช้มันในความคิดของฉัน
Federico

1
1) เราไม่ใช่เหรอ 2) โลกแห่งความจริงไม่ใช่เรื่องง่ายและ Unix เป็นระบบปฏิบัติการที่มีผู้ใช้หลายคน ผู้ใช้อาจเปลี่ยนการอนุญาตในไดเรกทอรีและหากสคริปต์หรือเปลือกโต้ตอบของผู้ใช้รายอื่นเกิดขึ้นมีไดเรกทอรีนั้น (หรือไดเรกทอรีย่อย) เป็นไดเรกทอรีการทำงานของมันcd .จะบ่น
Kusalananda

4
Federico ตามกฎของเว็บไซต์และกฎส่วนตัวของฉันเองฉันควรจะโหวตคำตอบของคุณ อย่างไรก็ตามคุณยังใหม่อยู่ ยินดีต้อนรับ! โปรดตรวจสอบบางส่วนของคำตอบอื่นหลังจากนั้นถ้าคุณคิดว่าคำตอบของคุณผิดโปรดลบออก กรุณาสนุกกับการให้คำตอบอื่น ๆ สำหรับคำถามนี้และอื่น ๆ
daveloyall

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