which コマンドの実装の書き直し

会社の先輩が python を勉強し始めました。それならっ!と簡単なサンプルを提示することにしました。以前、which コマンドを python で書いたことを思い出して探してみました。ちょうど python を勉強し始めたときで、約1年2ヶ月前に書いたコードが以下になります。

#!/usr/bin/env python                                  

import os
import sys
import glob

cmd_name = sys.argv[1]
path_list = [ item for item in os.environ['PATH'].split(':') ]
path_to_file = [ glob.glob(str(item) + '/' + cmd_name) for item in set(path_list) ]  # list comprehension
cmd_name)), path_list) # map function
path_to_cmd = "Not such command"

i=0
while i < len(path_to_file):
        for item in path_to_file[i]:
                if os.access(item, 1):
                        path_to_cmd = item
        i += 1

print path_to_cmd

今、見ると「何これ!?意味が分からん」と思ってしまいました(- -#
同じ標準モジュールを使っても、フツーに考えると、関数分割して、python らしくして、以下のようになりました(^ ^;;

#!/usr/bin/env python                                                        

import os
import sys
import glob

def main():
    """Script Main"""
    search_cmd = sys.argv[1:]
    search_path = os.environ['PATH'].split(':')
    for cmd in search_cmd:                     
        found_cmd = search_file(cmd, search_path)
        if found_cmd:
            print found_cmd
        else:
            print 'cannot find "%s" command' %(cmd)

def search_file(file, search_path):
    for path in search_path:
        for match in glob.glob(os.path.join(path, file)):
            if os.access(match, os.X_OK):
                return match

if __name__ == '__main__':
    main()

実行結果。

$ python which.py ls ifconfig vim detarame
/bin/ls
/sbin/ifconfig
/usr/bin/vim
cannot find "detarame" command

また1年後に書くと、さらに簡潔な実装になるかもしれません。先の駄コードも当時の私は一生懸命書いただろうけれど、日々勉強することの重要性を実感したひとときでした。