อะไรคือความแตกต่างระหว่างการรันโปรแกรมที่เรียกใช้โดยชื่อและต่อท้ายจุด / สแลชก่อนหน้า?


13

นี่คือผลลัพธ์จากls -allคำสั่ง:

-rwxr----- 1 subhrcho dba  3600 Nov 13 17:26 jdev
-rw-r----- 1 subhrcho dba  1566 Nov 13 17:26 jdev-Darwin.conf
-rw-r----- 1 subhrcho dba   347 Mar  6  2009 jdev-debug.boot
-rw-r----- 1 subhrcho dba   821 Nov 13 17:26 jdev-logging-debug.conf
-rw-r----- 1 subhrcho dba   584 Nov 13 17:26 jdev-logging.conf
-rw-r----- 1 subhrcho dba  4717 Jul 31 16:09 jdev.boot
-rw-r----- 1 subhrcho dba 12877 Nov 13 17:26 jdev.common
-rw-r----- 1 subhrcho dba  5047 Dec  6 01:43 jdev.conf
-rwxr-x--- 1 subhrcho dba 28160 Nov 13 16:28 jdev.exe
-rwxr-x--- 1 subhrcho dba 28672 Nov 13 16:28 jdev64.exe
-rwxr-x--- 1 subhrcho dba 28672 Nov 13 16:28 jdev64W.exe
-rwxr-x--- 1 subhrcho dba 28160 Nov 13 16:28 jdevW.exe

ตอนนี้เมื่อฉันเรียกใช้jdevมันรันOracle JDveloperเวอร์ชันอื่นมากกว่าตอนที่ฉันเรียกใช้เป็น./jdev.. ทำไมเป็นเช่นนั้น

คำตอบ:


20

เมื่อคุณเรียกใช้ไฟล์ปฏิบัติการ (หรือมากกว่าในยูนิกซ์ / linux world - ไฟล์ที่มีสิทธิเรียกใช้ / เปิดใช้งานแฟล็ก) ดังนี้:

$ ./jdev

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

(ดูการอนุญาตไฟล์ใน linux / unix )

เมื่อคุณเรียกใช้มันเป็น

$ jdev

ส่วนใหญ่แล้วมีการjdevติดตั้งที่ใดที่หนึ่งบนระบบและคุณมีไว้ใน$PATH(เช่น/usr/bin/หรือ/bin/หรือ/usr/local/bin/)

ตามที่peterphระบุไว้: คุณสามารถใช้whichเพื่อชี้ถึงปฏิบัติการที่กำลังเปิดตัวด้วยคำสั่งเฉพาะเช่น:

$ which find
/usr/bin/find

1
ไม่เช่นนั้นwhichยูทิลิตี้สามารถบอกคุณได้ว่าจะใช้ไฟล์ปฏิบัติการใดหากไม่ได้รับพา ธ
เตอร์

@peterph แก้ไขคำตอบของฉัน
Patryk

7
มันดีกว่าที่จะใช้typeเพื่อตรวจสอบสิ่งที่ถูกเรียกใช้โดยคำสั่งเฉพาะ สาเหตุwhichจะแสดงให้คุณเห็นเพียงไบนารีหนึ่งใน $ PATH อย่างไรก็ตามอาจเป็นชื่อแทนไบนารีอื่นอย่างแน่นอน
เร่ง

@rush [~] $which zsoelim /usr/bin/zsoelim [~] $ type zsoelim zsoelim is /usr/bin/zsoelimฉันได้พยายามเพียงแค่นั้นและมันจะไม่ทำงานตามที่คุณบอกว่า: ในขณะที่zsoelim -> soelim
Patryk

2
@ Patryk ฉันคิดว่ารัชหมายถึงนามแฝงของเชลล์ / ฟังก์ชั่นซึ่งwhichไม่มีโอกาสหาเพราะมันเป็นไบนารีแบบสแตนด์อโลนที่ไม่สามารถเข้าถึงสภาพแวดล้อมของเชลล์ที่กำลังทำงานอยู่ (ซึ่งฉันหมายถึงนามแฝงและฟังก์ชั่นไม่ใช่แค่ตัวแปรสภาพแวดล้อม ซึ่งบางส่วนได้รับการถ่ายทอด)
เตอร์

8

หากคุณเรียกคำสั่งที่ไม่มีเครื่องหมายสแลชในชื่อเชลล์แล้วมันจะค้นหาในเชลล์สมนามฟังก์ชันและในรายการพา ธ ที่ระบุใน$PATHตัวแปรสภาพแวดล้อม (โปรดทราบว่าคุณสามารถมีไดเรกทอรีการทำงานปัจจุบัน (ระบุว่าเป็น.หรือสตริงว่าง) หรือไดเรกทอรีญาติใด ๆ ใน$PATHแต่ไม่แนะนำให้เหตุผลด้านความปลอดภัย)

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

ดังนั้นหากคุณต้องการเรียกใช้คำสั่งที่เรียกfooว่าอยู่ในไดเรกทอรีการทำงานปัจจุบันคุณต้องสร้างชื่อที่มีเครื่องหมายทับ ./fooชัดเจนที่สุด คุณสามารถใช้เส้นทางแบบเต็มหรือ../dir/foo...

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


ทำไมไม่ "ซึ่ง" แต่ "พิมพ์"?
Geek

@ Geek, นั่นเป็นคำถามที่พบบ่อยที่นี่, ดูunix.stackexchange.com/search?q=dywhich Same+type
Stéphane Chazelas

คุณให้ลิงก์ที่ถูกต้องหรือไม่
Geek

นี่คือผลการค้นหาในเว็บไซต์นี้เพื่อพิสูจน์ว่าเป็นคำถามที่พบบ่อย whichคำตอบหลายคำถามเหล่านั้นจะบอกคุณว่าทำไมไม่ใช้ ดูตัวอย่างunix.stackexchange.com/questions/16693/ …
Stéphane Chazelas

2

ฉันแนะนำให้ใช้ Zsh's built-in 'where' (ดีกว่า 'which') เพื่อดูว่านามแฝงการสั่งซื้อ shell-in หรืออะไรจะถูกพบใน $ PATH ;-)

นี่คือตัวอย่างเพื่อทำความเข้าใจกับสิ่งต่าง ๆ ที่ดีขึ้นวิธีการเลือก:

[ 0:04:08 ] afsin@s15426859:~ % pwd
/home/afsin
[ 0:04:30 ] afsin@s15426859:~ % which who
/usr/bin/who
[ 0:04:47 ] afsin@s15426859:~ % where who
/usr/bin/who
/usr/bin/X11/who
[ 0:05:27 ] afsin@s15426859:~ % echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/home/afsin/bin
[ 0:05:31 ] afsin@s15426859:~ % touch who
[ 0:05:40 ] afsin@s15426859:~ % chmod +x who
[ 0:05:47 ] afsin@s15426859:~ % ls -al who
-rwxr-xr-x 1 afsin afsin 0 23. Jan 00:05 who
[ 0:05:50 ] afsin@s15426859:~ % where who
/usr/bin/who
/usr/bin/X11/who
[ 0:05:55 ] afsin@s15426859:~ % export PATH=$PATH:.
[ 0:06:09 ] afsin@s15426859:~ % where who
/usr/bin/who
/usr/bin/X11/who
./who
[ 0:06:14 ] afsin@s15426859:~ % alias who=who
[ 0:06:19 ] afsin@s15426859:~ % where who
who: aliased to who
/usr/bin/who
/usr/bin/X11/who
./who
[ 0:06:22 ] afsin@s15426859:~ % which who
who: aliased to who
[ 0:06:27 ] afsin@s15426859:~ %

1

แม้ว่าสิ่งนี้อาจขึ้นอยู่กับเชลล์ของคุณ แต่โดยทั่วไปก็คือ:

  • หากคุณระบุเส้นทางไม่ว่าจะเป็นแบบสัมพันธ์หรือแบบสัมบูรณ์เส้นทางนั้นจะถูกใช้ ./jdevเป็นเส้นทางสัมพัทธ์เพราะ.หมายถึงไดเรกทอรีปัจจุบัน (อันที่จริงls -all .จะให้เหมือนกับls -all) หากคุณเป็นเช่น/usr/bin/tool/นั้นคุณกำลังใช้เส้นทางที่แน่นอน ในกรณีเหล่านี้ไฟล์ที่ชี้ไปจะถูกเรียกใช้งาน

  • หากคุณไม่ได้ระบุเส้นทาง แต่เพียงชื่อไดเรกทอรีใน$PATHจะค้นหาเครื่องมือที่คุณพยายามเรียกใช้

หากคุณมีไฟล์ในไดเรกทอรีปัจจุบันที่มีชื่อเดียวกันกับไฟล์ในบางไดเรกทอรีใน$PATHและคุณเรียกใช้โดยต่อท้าย./ชื่อคุณจะสามารถเรียกใช้ไฟล์อื่นได้อย่างมีประสิทธิภาพ

บางทีปัญหาอื่นคือคุณคาดหวังว่าjdevจะเรียกใช้ไฟล์ปฏิบัติการในไดเรกทอรีปัจจุบัน เว้นแต่คุณ$PATHจะเปลี่ยน.เป็นสิ่งนี้ไม่ใช่สิ่งที่คุณควรคาดหวังเลย ...

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


คำศัพท์ของคุณสับสน jdevคนเดียวยังเป็นเส้นทางญาติ กฎคือ: ถ้ามันไม่มีสแลช, มันจะค้นหาในนามแฝง, ฟังก์ชั่นและ$PATH, มิฉะนั้น, มันถูกค้นหาโดยตรงบนระบบไฟล์ (แม้ว่าเชลล์บางตัวจะอนุญาตให้นามแฝงหรือฟังก์ชันที่มี / ในชื่อของพวกเขา precendence)
Stéphane Chazelas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.