ทำไมฉันต้องพิมพ์ `. / 'ก่อนดำเนินการโปรแกรมในไดเรกทอรีปัจจุบัน?


92

ในขณะที่รันโปรแกรม C, a.outโดยใช้เทอร์มิอูบุนตูทำไมฉันมักจะต้องพิมพ์./ก่อนที่จะa.outแทนการเพียงแค่เขียนa.out? มีวิธีแก้ปัญหานี้ไหม?




คำตอบ:


119

เมื่อคุณพิมพ์ชื่อของโปรแกรมเช่นa.outระบบจะค้นหาไฟล์ใน PATH ของคุณ ในระบบของฉัน PATH ถูกตั้งค่าเป็น

/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

ของคุณอาจจะคล้ายกัน ในการตรวจสอบให้ป้อนecho $PATHเทอร์มินัล

ระบบจะตรวจสอบไดเรกทอรีเหล่านี้ตามลำดับที่กำหนดและหากไม่พบโปรแกรมจะสร้างcommand not foundข้อผิดพลาด

การเตรียมคำสั่ง./อย่างมีประสิทธิภาพจะบอกว่า "ลืมเกี่ยวกับ PATH ฉันต้องการให้คุณดูเฉพาะในไดเรกทอรีปัจจุบัน"

ในทำนองเดียวกันคุณสามารถบอกให้ระบบค้นหาเฉพาะตำแหน่งอื่นโดยการเตรียมคำสั่งด้วยเส้นทางสัมพัทธ์หรือพา ธ สัมบูรณ์เช่น:

../หมายถึงในไดเรกทอรีหลักเช่น../helloมองหาสวัสดีในไดเรกทอรีหลัก

./Debug/hello: "ค้นหาhelloในไดเรกทอรีย่อย Debug ของไดเรกทอรีปัจจุบันของฉัน"

หรือ/bin/ls: "ค้นหาlsในไดเรกทอรี/bin"

โดยค่าเริ่มต้นไดเรกทอรีปัจจุบันไม่ได้อยู่ในเส้นทางเพราะถือว่าเป็นความเสี่ยงด้านความปลอดภัย ดูทำไม ไม่ได้อยู่ในเส้นทางโดยค่าเริ่มต้น? บน Superuser เพราะเหตุใด

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


25
นี้. +1 อย่าเพิ่ม.ในของคุณPATH(ตามคำแนะนำในอีก 2 คำตอบในปัจจุบัน) เนื่องจากความเสี่ยงด้านความปลอดภัยที่ระบุไว้ในคำตอบนี้
วันที่

8
นอกจากนี้ยังอาจเป็นที่น่าสังเกตว่าไม่มีอะไรพิเศษเกี่ยวกับ.ที่นี่คุณสามารถใช้เส้นทางแบบเต็มหรือแบบสัมพัทธ์เพื่อปฏิบัติการได้เช่น/home/user/foo/a.outหรือ./build/a.out
tobyodavies

@tobyodavies; จริงๆแล้ว.พิเศษเพราะมันหมายถึง "ไดเรกทอรีปัจจุบันของฉัน" และอาจเป็นไดเรกทอรีใด ๆ ที่ผู้ใช้พบว่าตนเองมีสิทธิ์อ่านและดำเนินการ นี่อาจเป็นอันตรายมากกว่าการเพิ่มเส้นทางที่ผ่านการรับรองโดยสมบูรณ์
Warren Hill

@WarrenHill เมื่อพิจารณาเพิ่มไปยังเส้นทางของคุณใช่มันแตกต่างกันมาก อย่างไรก็ตามในแง่ของไวยากรณ์ทุบตี.ไม่มีสถานะพิเศษมันเป็นเพียงเส้นทางที่อาจเริ่มต้นด้วย/และ./blahจะทำงานได้ดีกับcatหรือgrepเป็นพรอมต์ทุบตี
tobyodavies

@tobyodavies: ตกลงฉันได้แก้ไขคำตอบของฉันเพื่อรวมประเด็นของคุณ
Warren Hill

24

เหตุผลนี้ง่าย

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

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


1
คำอธิบายของคุณทำให้เข้าใจผิดมีความแตกต่างระหว่างคำสั่งในตัวในเชลล์และไฟล์ปฏิบัติการที่สามารถเข้าถึงได้ผ่านตัวแปร PATH แท้ที่จริงคำตอบของคุณยิ่งฉันอ่านมันรู้สึกไม่ถูกต้องมากขึ้น
Ahmed Masud

16

./เรียกใช้งานไฟล์ที่ไม่ได้อยู่ในของคุณ$PATHแต่จะเรียกใช้งานไฟล์ในไดเรกทอรีปัจจุบัน (หรืออีกไฟล์หนึ่งผ่าน./home/stefano/script.sh) ตอนนี้ PATH เป็นตัวแปรสภาพแวดล้อมที่มีสถานที่ทั้งหมดที่ทุบตีสามารถมองหาโปรแกรมที่ปฏิบัติการได้โดยไม่ต้องมีเส้นทางเต็ม (สัมบูรณ์) ไปที่พวกเขา

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

  • เมื่อคุณเรียกใช้คำสั่งหรือโปรแกรมพยายามสร้างexecsyscall (วิธีพิเศษของเคอร์เนลวิธีเริ่มต้นโปรแกรม) ระบบจะค้นหาไฟล์โดยไปที่แต่ละไดเรกทอรีใน PATH ของคุณ เมื่อพบโปรแกรมแล้วแม้ว่าจะอยู่ในหลายไดเรกทอรีการค้นหาจะถูกขัดจังหวะและพบครั้งแรกที่พบ

ในการเรียกใช้ไฟล์คุณจะต้องตั้งค่าบิตที่สามารถใช้งานได้ในการอนุญาต:

  • เนื่องจากคุณอยู่ในบรรทัดคำสั่งคุณจึงสามารถพิมพ์chmod +x finenameได้

  • หรือคุณสามารถตั้งค่าการอนุญาตโดยการคลิกขวาที่ไฟล์และเลือกคุณสมบัติ :

    ข้อความแสดงแทน

ตอนนี้คุณสามารถคัดลอกไฟล์ไปยังไดเรกทอรีในเส้นทางที่จะดูว่าคนที่อยู่ในที่นั่น - และพวกเขากำลังตั้งอยู่บนพื้นฐานต่อผู้ใช้ - echo $PATHประเภท

stefano@3000-G530:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

หากคุณสร้างไฟล์เรียกทำงานcatและย้ายไปที่ไฟล์นั้นจะ/usr/local/sbinถูกเรียกใช้แทนที่จะเป็นไฟล์ที่เหมาะสมcatซึ่งอยู่ใน/binนั้น คุณสามารถหาที่ไฟล์ของคุณโดยใช้และtype catwhereis cat


2
สิ่งหนึ่งที่ควรทราบ: คำถามของเขาดูเหมือนจะบ่งบอกว่าเขาได้รวบรวมและเชื่อมโยงบางสิ่งด้วยgccซึ่งจะตั้งค่าบิตรันไทม์โดยอัตโนมัติ
นาธานออสมัน

12

ทำไมคุณต้องพิมพ์./ก่อนดำเนินการโปรแกรม

ในเทอร์มินัลเมื่อใดก็ตามที่คุณพิมพ์ชื่อของแอปพลิเคชันสมมติว่าgeditเทอร์มินัลจะไปดูในบางไดเรกทอรี (ที่กำหนดไว้ล่วงหน้า) ที่มีแอปพลิเคชัน (ไบนารีของแอปพลิเคชัน) PATHชื่อของไดเรกทอรีเหล่านี้มีอยู่ในตัวแปรที่เรียกว่า echo $PATHคุณสามารถมองเห็นสิ่งที่อยู่ในตัวแปรนี้โดยการดำเนินการ ดูไดเรกทอรีเหล่านั้นคั่นด้วย:? เหล่านี้คือไดเรกทอรีที่ขั้วจะไปค้นหาในถ้าคุณเพียงแค่พิมพ์gedit, หรือnautilus a.outอย่างที่คุณเห็นเส้นทางของa.outโปรแกรมของคุณไม่อยู่ที่นั่น เมื่อคุณทำ./a.outคุณบอกขั้ว "มองในไดเรกทอรีปัจจุบันและเรียกใช้และไม่ได้ไปดูในa.outPATH

โซลูชันที่ 1

หากคุณไม่ต้องการพิมพ์./ทุกครั้งคุณจะต้องเพิ่มa.outไดเรกทอรี$PATHของ ในคำแนะนำต่อไปนี้ฉันจะสมมติว่าเส้นทางa.outเป็น/path/to/programs/แต่คุณควรเปลี่ยนเป็นเส้นทางจริงของคุณ

  1. เพียงเพิ่มบรรทัดต่อไปนี้ที่ท้ายไฟล์~/.pam_environment:

    PATH DEFAULT=${PATH}:/path/to/programs

    ที่มา: ตัวแปรสภาพแวดล้อมแบบถาวร

  2. ออกจากระบบและกลับเข้าสู่ระบบตอนนี้คุณจะสามารถเรียกใช้a.outโดยไม่ต้อง./จากไดเรกทอรีใด ๆ

หากคุณมีโปรแกรมอื่นในไดเรกทอรีอื่นคุณสามารถเพิ่มโปรแกรมเหล่านั้นในบรรทัดด้านบน อย่างไรก็ตามฉันขอแนะนำให้มีไดเรกทอรีหนึ่งชื่อ "myPrograms" และวางโปรแกรมทั้งหมดของคุณไว้ในนั้น

โซลูชันที่ 2

หมายเหตุ:เปลี่ยนuserNameเป็นชื่อผู้ใช้ Ubuntu จริงของคุณ

ถ้าคุณมีโปรแกรมอื่นที่คุณต้องการรัน และพวกเขาทั้งหมดในโฟลเดอร์ที่แตกต่างกันอย่างไร วิธีการแก้ปัญหาที่ "จัดระเบียบมากขึ้น" คือการสร้างโฟลเดอร์ที่เรียกว่าbinภายใต้โฮมไดเร็กตอรี่ของคุณและเพิ่มลิงค์สัญลักษณ์ (ทางลัด) ใต้โฟลเดอร์นั้น นี่คือวิธี:

  1. mkdir /home/userName/bin

    • สิ่งนี้จะสร้างโฟลเดอร์binภายใต้ไดเรกทอรีบ้านของคุณ
  2. ln -s /path/to/programs/a.out /home/userName/bin

    • นี้จะสร้าง "การเชื่อมโยงสัญลักษณ์" (โดยทั่วไปทางลัด) ของคุณโปรแกรมภายใต้a.outbin
  3. ออกจากระบบและกลับเข้าสู่ระบบตอนนี้คุณจะสามารถเรียกใช้a.outโดยไม่ต้อง./จากไดเรกทอรีใด ๆ

ตอนนี้เมื่อใดก็ตามที่คุณมีโปรแกรมอื่นที่อื่นสมมติว่าโปรแกรมb.inบนเดสก์ท็อปของคุณสิ่งที่คุณต้องทำคือ: ln -s /home/userName/Desktop/b.in /home/userName/binแล้วคุณจะสามารถเรียกใช้โปรแกรมได้โดยไม่ต้องทำ./เช่นนั้น

หมายเหตุ:ต้องขอบคุณความคิดเห็นของ @ Joeเมื่อคุณสำรองข้อมูลลิงก์สัญลักษณ์ต้องได้รับการจัดการเป็นพิเศษ ตามค่าเริ่มต้นrsyncจะไม่ประมวลผลเลยดังนั้นเมื่อคุณกู้คืนจะไม่มีการดำเนินการ


1
นี่คือเคล็ดลับที่มีประโยชน์หากมีการใช้เท่าที่จำเป็น การใช้งานจำนวนมากทำให้ระบบของคุณทำสิ่งที่คนอื่นไม่คาดคิด นอกจากนี้เมื่อคุณสำรองข้อมูล symlink จะต้องได้รับการจัดการเป็นพิเศษ โดยค่าเริ่มต้น rsync จะไม่ประมวลผลเลยดังนั้นเมื่อคุณกู้คืนพวกเขาไม่ได้อยู่ที่นั่น
Joe

1

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

ฉันจำได้ว่าถามคำถามนี้กับผู้อาวุโสของฉันมานานแล้วเขาบอกว่าฉันควรเพิ่ม.เส้นทางของฉันเพื่อที่เมื่อฉันa.outดูในไดเรกทอรีปัจจุบันและดำเนินการนั้น ./a.outในกรณีนี้ผมไม่ต้องทำ

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


ok, สเตฟาโนนำมาใช้คำตอบของเขาที่จะมีข้อมูลนี้ :)
Shrikant Sharat

3
ผมเห็นด้วยกับไม่เพิ่มไป. $PATHความคิดที่อันตรายมาก
นาธานออสมัน

1

นอกจากคำตอบอื่น ๆ นี่คือส่วนสำคัญman bashที่อธิบายได้ดี:

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

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

       หากชื่อไม่ใช่ทั้งฟังก์ชันของเชลล์และในตัวและไม่มี
       เครื่องหมายทับ, ทุบตีค้นหาแต่ละองค์ประกอบของเส้นทางสำหรับการเชื่อมโยงไดเรกทอรี
       การจัดการไฟล์ที่สามารถเรียกทำงานได้โดยใช้ชื่อนั้น

0

'./' เหมาะสมเมื่อคุณเรียกใช้โปรแกรมที่เป็นที่รู้จักสำหรับคุณและเจาะจงเช่นโปรแกรมของคุณเอง โปรแกรมนี้จะต้องมีอยู่ในไดเรกทอรีปัจจุบันของคุณ A './' ไม่สมเหตุสมผลเมื่อคุณเรียกใช้คำสั่งมาตรฐานที่อยู่ในตำแหน่ง $ PATH คำสั่ง "ซึ่งเรียกใช้คำสั่ง" จะบอกให้คุณทราบว่าคำสั่งรันที่ใดใน $ PATH


0
$ gcc hello.c -o /path/to/someplace/hello

จะสร้างไฟล์ปฏิบัติการในบางตำแหน่ง หากตำแหน่งนั้นอยู่บนเส้นทางของคุณคุณจะสามารถเรียกใช้ไฟล์ได้ คุณสามารถเขียนสคริปต์นี้หากคุณต้องการสร้างป้ายกำกับสำหรับการกระทำ "รวบรวมซอร์สโค้ดนี้โดยใช้ gcc และวางไฟล์ปฏิบัติการไว้ที่ตำแหน่งที่อยู่บนเส้นทางของคุณ"

ฉันขอแนะนำให้คุณสร้างไดเรกทอรีใหม่ที่เรียกว่า "testbin" หรือสิ่งที่จัดเรียงและวางไว้บนเส้นทางของคุณเพื่อให้ไดเรกทอรีเส้นทางที่มีอยู่ของคุณสะอาด


0

./กำจัดการค้นหาที่ไม่จำเป็นสำหรับเส้นทาง ./บังคับให้ค้นหาในไดเรกทอรีปัจจุบันเท่านั้น ถ้าเราไม่ได้ให้./แล้วมันจะค้นหาเส้นทางต่างๆตั้งเข้าไปในระบบเช่น/usr/bin, /usr/sbin/ฯลฯ


0

"./" หมายความว่าคุณต้องการเรียกใช้ไฟล์ในไดเรกทอรีปัจจุบันซึ่งเป็นทางลัดในการพิมพ์เส้นทางทั้งหมดเช่น:

[root@server ~]#/path/to/file/file.pl

เหมือนกับ:

[root@server file]#./file.pl

ในตัวอย่างก่อนหน้านี้คุณผ่านไดเรกทอรีและ sup-directory ไปยังตำแหน่งไฟล์และใช้ "./" เพื่อเรียกใช้ไฟล์ในไดเรกทอรีปัจจุบัน

สิ่งที่อยู่ข้างหน้า " [root @ server ~] # / path / to / file / file.pl " จะทำการเรียกใช้ไฟล์หากคุณขี้เกียจที่จะ "cd" ไปยังตำแหน่งของไฟล์


-4

มันง่ายมากและมีประโยชน์หลายอย่าง

  1. เมื่อหลายรุ่นของโปรแกรมเดียวกันมีการติดตั้งก็จะสามารถใช้ได้ในเส้นทางที่แตกต่างกัน /usr/binแต่การเชื่อมโยงนุ่มไบนารีของคุณสามารถสร้างใน ตัวอย่างเช่นติดตั้ง Python 2.7, Python 2.6 แต่ / usr / bin / python -> python2.7 / usr / local / bin / python -> python2.6

หากคุณอยู่ในเส้นทาง/usr/local/binและดำเนินการ Python มันจะดำเนินการ Python 2.7 เสมอ การระบุ.จะใช้ไฟล์ปฏิบัติการของโฟลเดอร์ปัจจุบัน

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