ในขณะที่รันโปรแกรม C, a.out
โดยใช้เทอร์มิอูบุนตูทำไมฉันมักจะต้องพิมพ์./
ก่อนที่จะa.out
แทนการเพียงแค่เขียนa.out
? มีวิธีแก้ปัญหานี้ไหม?
ในขณะที่รันโปรแกรม C, a.out
โดยใช้เทอร์มิอูบุนตูทำไมฉันมักจะต้องพิมพ์./
ก่อนที่จะa.out
แทนการเพียงแค่เขียนa.out
? มีวิธีแก้ปัญหานี้ไหม?
คำตอบ:
เมื่อคุณพิมพ์ชื่อของโปรแกรมเช่น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 ของคุณ แต่ด้วยเหตุผลที่กำหนดในคำถามที่เชื่อมโยงฉันจะไม่แนะนำ
.
ในของคุณPATH
(ตามคำแนะนำในอีก 2 คำตอบในปัจจุบัน) เนื่องจากความเสี่ยงด้านความปลอดภัยที่ระบุไว้ในคำตอบนี้
.
ที่นี่คุณสามารถใช้เส้นทางแบบเต็มหรือแบบสัมพัทธ์เพื่อปฏิบัติการได้เช่น/home/user/foo/a.out
หรือ./build/a.out
.
พิเศษเพราะมันหมายถึง "ไดเรกทอรีปัจจุบันของฉัน" และอาจเป็นไดเรกทอรีใด ๆ ที่ผู้ใช้พบว่าตนเองมีสิทธิ์อ่านและดำเนินการ นี่อาจเป็นอันตรายมากกว่าการเพิ่มเส้นทางที่ผ่านการรับรองโดยสมบูรณ์
.
ไม่มีสถานะพิเศษมันเป็นเพียงเส้นทางที่อาจเริ่มต้นด้วย/
และ./blah
จะทำงานได้ดีกับcat
หรือgrep
เป็นพรอมต์ทุบตี
เหตุผลนี้ง่าย
สมมติว่าคุณมีคำสั่งที่มีชื่อเดียวกันกับแอปพลิเคชันในไดเรกทอรีปัจจุบัน จากนั้นการรันคำสั่งในเชลล์จะเรียกใช้แอปของคุณแทนคำสั่งในตัว นี่จะเป็นความกังวลด้านความปลอดภัยหากไม่มีอะไรอื่น
เมื่อต้องการ./
ให้ใช้งานด้านหน้าเชลล์จะรู้ว่าคุณต้องการรันแอปพลิเคชันด้วยชื่อที่กำหนดไม่ใช่คำสั่งในตัวที่มีชื่อนั้น
./
เรียกใช้งานไฟล์ที่ไม่ได้อยู่ในของคุณ$PATH
แต่จะเรียกใช้งานไฟล์ในไดเรกทอรีปัจจุบัน (หรืออีกไฟล์หนึ่งผ่าน./home/stefano/script.sh
) ตอนนี้ PATH เป็นตัวแปรสภาพแวดล้อมที่มีสถานที่ทั้งหมดที่ทุบตีสามารถมองหาโปรแกรมที่ปฏิบัติการได้โดยไม่ต้องมีเส้นทางเต็ม (สัมบูรณ์) ไปที่พวกเขา
การแยกนี้จำเป็นเพื่อหลีกเลี่ยงการเรียกใช้ไฟล์ผิด เช่นถ้าคุณมีไฟล์ที่เรียกว่าในไดเรกทอรีบ้านของคุณก็ไม่ได้อยู่ในเส้นทางของคุณจะป้องกันไม่ให้เกิดความสับสนจากการทุบตีด้วยจริงls
ls
ตัวแปร PATH ยังกำหนดลำดับการค้นหา:
exec
syscall (วิธีพิเศษของเคอร์เนลวิธีเริ่มต้นโปรแกรม) ระบบจะค้นหาไฟล์โดยไปที่แต่ละไดเรกทอรีใน 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 cat
whereis cat
gcc
ซึ่งจะตั้งค่าบิตรันไทม์โดยอัตโนมัติ
./
ก่อนดำเนินการโปรแกรมในเทอร์มินัลเมื่อใดก็ตามที่คุณพิมพ์ชื่อของแอปพลิเคชันสมมติว่าgedit
เทอร์มินัลจะไปดูในบางไดเรกทอรี (ที่กำหนดไว้ล่วงหน้า) ที่มีแอปพลิเคชัน (ไบนารีของแอปพลิเคชัน) PATH
ชื่อของไดเรกทอรีเหล่านี้มีอยู่ในตัวแปรที่เรียกว่า echo $PATH
คุณสามารถมองเห็นสิ่งที่อยู่ในตัวแปรนี้โดยการดำเนินการ ดูไดเรกทอรีเหล่านั้นคั่นด้วย:
? เหล่านี้คือไดเรกทอรีที่ขั้วจะไปค้นหาในถ้าคุณเพียงแค่พิมพ์gedit
, หรือnautilus
a.out
อย่างที่คุณเห็นเส้นทางของa.out
โปรแกรมของคุณไม่อยู่ที่นั่น เมื่อคุณทำ./a.out
คุณบอกขั้ว "มองในไดเรกทอรีปัจจุบันและเรียกใช้และไม่ได้ไปดูในa.out
PATH
หากคุณไม่ต้องการพิมพ์./
ทุกครั้งคุณจะต้องเพิ่มa.out
ไดเรกทอรี$PATH
ของ ในคำแนะนำต่อไปนี้ฉันจะสมมติว่าเส้นทางa.out
เป็น/path/to/programs/
แต่คุณควรเปลี่ยนเป็นเส้นทางจริงของคุณ
เพียงเพิ่มบรรทัดต่อไปนี้ที่ท้ายไฟล์~/.pam_environment
:
PATH DEFAULT=${PATH}:/path/to/programs
ที่มา: ตัวแปรสภาพแวดล้อมแบบถาวร
ออกจากระบบและกลับเข้าสู่ระบบตอนนี้คุณจะสามารถเรียกใช้a.out
โดยไม่ต้อง./
จากไดเรกทอรีใด ๆ
หากคุณมีโปรแกรมอื่นในไดเรกทอรีอื่นคุณสามารถเพิ่มโปรแกรมเหล่านั้นในบรรทัดด้านบน อย่างไรก็ตามฉันขอแนะนำให้มีไดเรกทอรีหนึ่งชื่อ "myPrograms" และวางโปรแกรมทั้งหมดของคุณไว้ในนั้น
หมายเหตุ:เปลี่ยน
userName
เป็นชื่อผู้ใช้ Ubuntu จริงของคุณ
ถ้าคุณมีโปรแกรมอื่นที่คุณต้องการรัน และพวกเขาทั้งหมดในโฟลเดอร์ที่แตกต่างกันอย่างไร วิธีการแก้ปัญหาที่ "จัดระเบียบมากขึ้น" คือการสร้างโฟลเดอร์ที่เรียกว่าbin
ภายใต้โฮมไดเร็กตอรี่ของคุณและเพิ่มลิงค์สัญลักษณ์ (ทางลัด) ใต้โฟลเดอร์นั้น นี่คือวิธี:
mkdir /home/userName/bin
bin
ภายใต้ไดเรกทอรีบ้านของคุณln -s /path/to/programs/a.out /home/userName/bin
a.out
bin
ออกจากระบบและกลับเข้าสู่ระบบตอนนี้คุณจะสามารถเรียกใช้a.out
โดยไม่ต้อง./
จากไดเรกทอรีใด ๆ
ตอนนี้เมื่อใดก็ตามที่คุณมีโปรแกรมอื่นที่อื่นสมมติว่าโปรแกรมb.in
บนเดสก์ท็อปของคุณสิ่งที่คุณต้องทำคือ: ln -s /home/userName/Desktop/b.in /home/userName/bin
แล้วคุณจะสามารถเรียกใช้โปรแกรมได้โดยไม่ต้องทำ./
เช่นนั้น
หมายเหตุ:ต้องขอบคุณความคิดเห็นของ @ Joeเมื่อคุณสำรองข้อมูลลิงก์สัญลักษณ์ต้องได้รับการจัดการเป็นพิเศษ ตามค่าเริ่มต้น
rsync
จะไม่ประมวลผลเลยดังนั้นเมื่อคุณกู้คืนจะไม่มีการดำเนินการ
ดังที่จอร์จชี้ให้เห็นในคำตอบของเขาสิ่งนี้จะช่วยให้คุณทราบว่าการเรียกใช้ไฟล์ของคุณในไดเรกทอรีทำงานปัจจุบัน ( pwd
)
ฉันจำได้ว่าถามคำถามนี้กับผู้อาวุโสของฉันมานานแล้วเขาบอกว่าฉันควรเพิ่ม.
เส้นทางของฉันเพื่อที่เมื่อฉันa.out
ดูในไดเรกทอรีปัจจุบันและดำเนินการนั้น ./a.out
ในกรณีนี้ผมไม่ต้องทำ
แต่โดยส่วนตัวฉันขอแนะนำให้ต่อต้าน มันไม่เคยเกิดขึ้นกับฉัน แต่ถ้าคุณอยู่ในไดเรกทอรีเครือข่ายคนต่างด้าวหรืออะไรและไฟล์ปฏิบัติการที่เป็นอันตรายที่เรียกว่าls
มีอยู่แล้วมี.
ในเส้นทางของคุณเป็นความคิดที่ดีมาก ไม่ใช่ว่าคุณจะเจอปัญหานี้บ่อยมากเพียงแค่พูดว่า
.
$PATH
ความคิดที่อันตรายมาก
นอกจากคำตอบอื่น ๆ นี่คือส่วนสำคัญman bash
ที่อธิบายได้ดี:
การปฏิบัติตามคำสั่ง หลังจากคำสั่งถูกแบ่งออกเป็นคำต่าง ๆ หากคำสั่งนั้นง่าย คำสั่งและรายการอาร์กิวเมนต์ที่เป็นทางเลือกการดำเนินการต่อไปนี้คือ ยึด หากชื่อคำสั่งไม่มีเครื่องหมายสแลชเชลล์จะพยายามค้นหา มัน. หากมีฟังก์ชันเชลล์ตามชื่อฟังก์ชันนั้นคือ เรียกใช้ตามที่อธิบายไว้ข้างต้นในฟังก์ชั่น หากชื่อไม่ตรงกับ ฟังก์ชั่นเปลือกค้นหาในรายการของเชลล์บิวด์ ถ้า พบคู่ที่ถูกสร้างขึ้นภายในจะถูกเรียกใช้ หากชื่อไม่ใช่ทั้งฟังก์ชันของเชลล์และในตัวและไม่มี เครื่องหมายทับ, ทุบตีค้นหาแต่ละองค์ประกอบของเส้นทางสำหรับการเชื่อมโยงไดเรกทอรี การจัดการไฟล์ที่สามารถเรียกทำงานได้โดยใช้ชื่อนั้น
'./' เหมาะสมเมื่อคุณเรียกใช้โปรแกรมที่เป็นที่รู้จักสำหรับคุณและเจาะจงเช่นโปรแกรมของคุณเอง โปรแกรมนี้จะต้องมีอยู่ในไดเรกทอรีปัจจุบันของคุณ A './' ไม่สมเหตุสมผลเมื่อคุณเรียกใช้คำสั่งมาตรฐานที่อยู่ในตำแหน่ง $ PATH คำสั่ง "ซึ่งเรียกใช้คำสั่ง" จะบอกให้คุณทราบว่าคำสั่งรันที่ใดใน $ PATH
$ gcc hello.c -o /path/to/someplace/hello
จะสร้างไฟล์ปฏิบัติการในบางตำแหน่ง หากตำแหน่งนั้นอยู่บนเส้นทางของคุณคุณจะสามารถเรียกใช้ไฟล์ได้ คุณสามารถเขียนสคริปต์นี้หากคุณต้องการสร้างป้ายกำกับสำหรับการกระทำ "รวบรวมซอร์สโค้ดนี้โดยใช้ gcc และวางไฟล์ปฏิบัติการไว้ที่ตำแหน่งที่อยู่บนเส้นทางของคุณ"
ฉันขอแนะนำให้คุณสร้างไดเรกทอรีใหม่ที่เรียกว่า "testbin" หรือสิ่งที่จัดเรียงและวางไว้บนเส้นทางของคุณเพื่อให้ไดเรกทอรีเส้นทางที่มีอยู่ของคุณสะอาด
./
กำจัดการค้นหาที่ไม่จำเป็นสำหรับเส้นทาง ./
บังคับให้ค้นหาในไดเรกทอรีปัจจุบันเท่านั้น ถ้าเราไม่ได้ให้./
แล้วมันจะค้นหาเส้นทางต่างๆตั้งเข้าไปในระบบเช่น/usr/bin
, /usr/sbin/
ฯลฯ
"./" หมายความว่าคุณต้องการเรียกใช้ไฟล์ในไดเรกทอรีปัจจุบันซึ่งเป็นทางลัดในการพิมพ์เส้นทางทั้งหมดเช่น:
[root@server ~]#/path/to/file/file.pl
เหมือนกับ:
[root@server file]#./file.pl
ในตัวอย่างก่อนหน้านี้คุณผ่านไดเรกทอรีและ sup-directory ไปยังตำแหน่งไฟล์และใช้ "./" เพื่อเรียกใช้ไฟล์ในไดเรกทอรีปัจจุบัน
สิ่งที่อยู่ข้างหน้า " [root @ server ~] # / path / to / file / file.pl " จะทำการเรียกใช้ไฟล์หากคุณขี้เกียจที่จะ "cd" ไปยังตำแหน่งของไฟล์
มันง่ายมากและมีประโยชน์หลายอย่าง
/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 เสมอ การระบุ.
จะใช้ไฟล์ปฏิบัติการของโฟลเดอร์ปัจจุบัน
.
- แสดงถึงการดำเนินการจากไดเรกทอรีปัจจุบันเสมอ และ..
หมายถึงการเรียกใช้งานจากไดเรกทอรีก่อนหน้าเสมอ