在 Ubuntu 下執行指令後, 若沒有安裝指令的話, 會出現提示:
$ apt-rdepends
The program 'apt-rdepends' is currently not installed. You can install it by typing:
sudo apt-get install apt-rdepends
但若直接用 bash 執行, 卻不會有這效果:
$ bash -c apt-rdepends
bash: apt-rdepends: command not found
以前覺得很好奇, Ubuntu 怎麼做到這件事的, 知道 strace 以後, 追這類原因簡單許多, 只要有輸入和輸出訊息, 就可夾擊出一些線索。
搜一下 "apt-rdepends" 會看到 bash 在嘗試各種 path 後都找不到檔案:
16520 stat("/home/fcamel/bin/apt-rdepends", 0x...) = -1 ENOENT...
16520 stat("/usr/local/sbin/apt-rdepends", 0x...) = -1 ENOENT...
16520 stat("/usr/local/bin/apt-rdepends", 0x...) = -1 ENOENT...
16520 stat("/usr/sbin/apt-rdepends", 0x...) = -1 ENOENT...
16520 stat("/usr/bin/apt-rdepends", 0x...) = -1 ENOENT...
16520 stat("/sbin/apt-rdepends", 0x...) = -1 ENOENT...
16520 stat("/bin/apt-rdepends", 0x...) = -1 ENOENT...
16520 stat("/usr/games/apt-rdepends", 0x...) = -1 ENOENT...
16520 stat("/home/fcamel/bin/apt-rdepends", 0x...) = -1 ENOENT...
16520 stat("/home/fcamel/bin/apt-rdepends", 0x...) = -1 ENOENT...
之後在別的 child process 呼叫外部程式執行 /usr/lib/command-not-found:
16877 execve("/usr/bin/python", ["/usr/bin/python", "/usr/lib/command-not-found", "--", "apt-rdepends"], [/* 38 vars */]) = 0
若想研究怎麼找出該裝的套件, 可以研究 "/usr/lib/command-not-found"。若想研究 bash 如何判斷在有 terminal 的情況下要多找安裝的指令, 可以自己編含 debug symbol 的 bash, 再用 gdb 找出相關位置, 再讀附近的原始碼。這樣一來, 至少知道需要追的時候該如何進行, 剩下就是增加經驗提昇追程式的速度了。
2012-01-23 更新
經 wens 提醒, 原來是用 bash 的 hook 做的, 見 /etc/bash.bashrc 瞭解設定, man bash 在 COMMAND EXECUTION 那節有說明。