คำสั่ง `ซึ่ง` อาจจะผิด (บางครั้ง)?


17

ฉันได้รวบรวมเวอร์ชั่น emacs ล่าสุดจากซอร์สโค้ด (v24.2) เพราะเวอร์ชันที่ติดตั้งในเครื่องของฉันนั้นค่อนข้างเก่าสำหรับฉัน (v21.3) ฉันทำตามปกติ:

$configure --prefix=$HOME
make 
make install

ตอนนี้ฉันกำลังทดสอบ emacs และรู้ว่ามันยังคงเปิดตัวรุ่นก่อนหน้า ... ในขณะที่$HOME/binเส้นทางของฉันควรจะแทนที่ระบบหนึ่ง (เนื่องจากมีการเติมไว้ที่ $ PATH ใน.bashrcไฟล์ของฉัน)

ความคิดแรกของฉันคือการเห็นwhichผลลัพธ์ของคำสั่ง และน่าประหลาดใจมันทำให้เส้นทางไปสู่ ​​emacs ใหม่ ฉันไม่เข้าใจความแตกต่างของที่นี่ ในเซสชันเดียวกันนี่คือผลลัพธ์ที่ต่างกัน:

$ emacs --version
GNU Emacs 21.3.1

$ `which emacs` --version
GNU Emacs 24.2.1

ฉันไม่มีนามแฝงที่เกี่ยวข้องกับ emacs เลย

$ alias | grep emacs
$

ความคิดใดที่เกิดขึ้นได้โปรด


emacs ใดที่กลับมา?
Ulrich Dangel

คำตอบ:


29

ความเป็นไปได้สามอย่างที่เข้ามาในใจสำหรับฉัน:

  • มีชื่อแทนemacs(ซึ่งคุณได้ตรวจสอบแล้ว)
  • มีฟังก์ชันสำหรับ emacs
  • emacsไบนารีใหม่ไม่ได้อยู่ใน hashtable PATH ของเชลล์

คุณสามารถตรวจสอบว่าคุณมีฟังก์ชั่นemacs:

bash-3.2$ declare -F | fgrep emacs
declare -f emacs

และลบมัน:

unset -f emacs

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

hash -r

คำอธิบายเพิ่มเติม:

which ไม่ทราบเกี่ยวกับฟังก์ชั่นเนื่องจากมันไม่ใช่ bash builtin:

bash-3.2$ emacs() { echo 'no emacs for you'; }
bash-3.2$ emacs
no emacs for you
bash-3.2$ which emacs
/usr/bin/emacs
bash-3.2$ `which emacs` --version | head -1
GNU Emacs 22.1.1

สคริปต์ hashtable แบบไบนารีใหม่นี้แสดงให้เห็นถึง

bash-3.2$ PATH=$HOME/bin:$PATH
bash-3.2$ cd $HOME/bin

bash-3.2$ cat nofile
cat: nofile: No such file or directory
bash-3.2$ echo echo hi > cat
bash-3.2$ chmod +x cat
bash-3.2$ cat nofile
cat: nofile: No such file or directory

bash-3.2$ hash -r
bash-3.2$ cat nofile
hi
bash-3.2$ rm cat
bash-3.2$ cat nofile
bash: /Users/mrb/bin/cat: No such file or directory

bash-3.2$ hash -r
bash-3.2$ cat nofile
cat: nofile: No such file or directory

แม้ว่าฉันจะไม่ได้เรียกมัน แต่which catจะคืนค่าเป็นครั้งแรกcatใน PATH ของฉันเพราะมันไม่ได้ใช้ hashtable ของเชลล์


1
ในขณะที่มีข้อมูลที่ดีที่นี่ก็คิดถึงtypeคำสั่ง
จอร์แดน

ขอบคุณฉันมีปัญหาเดียวกันกับ sqlite3 รุ่นที่คอมไพล์ใหม่ซึ่งทำให้ฉัน nut (ซึ่งอันที่จริงกลับเส้นทางที่ถูกต้อง แต่เชลล์ไม่ได้เรียก sqlite3 cli ที่ถูกต้อง) hash -rแก้ไขปัญหาของฉันแล้ว
mpm

12

ใช่อย่าใช้สิ่งใด :

  • ในบางระบบก็เป็นคำสั่งภายนอกดำเนินการตามสคริปต์ csh PATHซึ่งอาจอ่านการกำหนดค่าที่มีการเปลี่ยนแปลงได้
  • มี builtin สำหรับสิ่งนั้น สองแม้: และtype commandวิธี POSIX:

    command -v emacs       # machine-readable format
    type emacs             # human-only format
    

    ในทุบตีคุณยังสามารถใช้type -p emacsเพื่อดูเพียงเส้นทางของคำสั่งภายนอก

อย่างไรก็ตามที่นี่whichถูกต้องจริง Bash เก็บข้อมูลเกี่ยวกับตำแหน่งของคำสั่งในหน่วยความจำเพื่อให้สามารถดำเนินการคำสั่งได้เร็วขึ้นในครั้งต่อไป คุณได้ติดตั้งemacsไฟล์ปฏิบัติการใหม่ของคุณPATHแล้ว แต่ทุบตียังคงมีตำแหน่งเดิมในแคช เรียกใช้hash emacsเพื่อค้นหาemacsอีกครั้งหรือhash -rล้างแคช


1

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


หากเป็นเช่นนั้น`which emacs` --versionจะเห็นด้วยemacs --versionเพราะwhichสืบทอด PATH จากเชลล์ปัจจุบัน
mrb

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