PyAutoGuiでlocateCenterOnScreenが動かない

# あらまし

```py3
import pyautogui as pa
position = pa.locateCenterOnScreen("target.png")
```
`locateOnScreen("target.png")`は画面内にあるtarget.pngと一致する場所の中心の座標を出力する. 

```py3tb
Traceback (most recent call last):
  File "test.py", line 5, in <module>
    position = pa.locateCenterOnScreen("target.png")
  File "/home/USER/.pyenv/versions/anaconda3-4.1.1/lib/python3.5/site-packages/pyscreeze/__init__.py", line 122, in locateCenterOnScreen
    return center(locateOnScreen(image, grayscale))
  File "/home/USER/.pyenv/versions/anaconda3-4.1.1/lib/python3.5/site-packages/pyscreeze/__init__.py", line 105, in locateOnScreen
    screenshotIm = screenshot()
  File "/home/USER/.pyenv/versions/anaconda3-4.1.1/lib/python3.5/site-packages/pyscreeze/__init__.py", line 156, in _screenshot_linux
    raise NotImplementedError('"scrot" must be installed to use screenshot functions in Linux. Run: sudo apt-get install scrot')
NotImplementedError: "scrot" must be installed to use screenshot functions in Linux. Run: sudo apt-get install scrot
```
怒られてしまった. 

## 実行環境
OS : Ubuntu 16.04 LTS
Shell : Zsh
Python : anaconda3-4.1.1 on pyenv


## 何を怒っているの？
「`scrot`がないよ」と言われているが, もう既に導入している(`scrot`はターミナルからスクリーンショットを撮るコマンド). どうやら**`pyautogui`ではなく`pyscreeze`からエラーが飛んでいるらしい.** `.../pyscreeze/__init__.py`の`scrot`がインストールされているかどうかを判断するメソッドがちゃんと動いていないのかもしれない. 

# 調査
`.../pyscreeze/__init__.py`内の変数`scrotExists`が`scrot`の有無を管理している:

```py3
try:
    if sys.platform not in ('java', 'darwin', 'win32'):
        whichProc = subprocess.Popen(['which', 'scrot'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        scrotExists = whichProc.wait() == 0
        
except:
    # if there is no "which" program to find scrot, then assume there is no scrot.
    pass
```
「`scrot`がないよ」と怒ってくるのは`scrotExists`がFalseになっているということ. `subprocess.Popen().wait()`が期待通りに動いていないのだろう. いろいろ手を動かしてみた結果, `shell=True`が怪しい.
## Popen
`shell=True`を指定すると, Ubuntuでは実行するシェルが`/bin/sh`になるらしい. `shell=False`だと自分の環境ではzshで実行される:

```py3
>>> sp.Popen("echo $0", shell=True).wait()
/bin/sh
0

>>> sp.Popen(["ps"]).wait()
  PID TTY          TIME CMD
 2418 pts/20   00:00:00 python
 2871 pts/20   00:00:00 ps
21011 pts/20   00:00:00 zsh
26515 pts/20   00:00:24 emacs
0
```
戻り値のゼロはリターンコード. 正常終了している. 見ての通り, "shell"の指定によってコマンドの書式が違う. 前者は`string`, 後者は`list`を渡している. `/bin/sh`が悪さしてるのかなと思いきや, そうではなかった. 結局, 「`shell=True`かつ`string`で渡す」か「`shell=False`かつ`list`で渡す」かのどちらかではうまくいった. ちゃんと調べていないが, pythonのバージョンで`subprocess.popen()`の仕様が違うのか, はたまた別の理由か. 

これでうまく行くかと思いきや, まだ怒られる:

```py3tb
Traceback (most recent call last):
  File "test.py", line 5, in <module>
    position = pa.locateCenterOnScreen("images/target.png")
  File "/home/USER/.pyenv/versions/anaconda3-4.1.1/lib/python3.5/site-packages/pyscreeze/__init__.py", line 120, in locateCenterOnScreen
    return center(locateOnScreen(image, grayscale))
  File "/home/USER/.pyenv/versions/anaconda3-4.1.1/lib/python3.5/site-packages/pyscreeze/__init__.py", line 106, in locateOnScreen
    screenshotIm.fp.close() # Screenshots on Windows won't have an fp since they came from ImageGrab, not a file.
AttributeError: 'NoneType' object has no attribute 'close'
```
「`screenshotIm.fp`が`NonType`だよ」と. もしcloseしなければならないオブジェクトだとしても, デストラクタがフォローしてくれるだろうと高をくくってこの部分をコメントアウト. 結果ちゃんと動いた. 

# 教訓
とりあえず動いたのでgithubにPullRequestを投げようと思ったら, [既に修正されていた](https://github.com/asweigart/pyscreeze/blob/master/pyscreeze/__init__.py):

```py3
def locateAllOnScreen(image, **kwargs):
    screenshotIm = screenshot(region=None) # the locateAll() function must handle cropping to return accurate coordinates, so don't pass a region here.
    retVal = locateAll(image, screenshotIm, **kwargs)
    try:
        screenshotIm.fp.close()
    except AttributeError:
        # Screenshots on Windows won't have an fp since they came from
        # ImageGrab, not a file. Screenshots on Linux will have fp set
        # to None since the file has been unlinked
        pass
    return retVal
```
ご丁寧なコメント付き. バージョンを見てみるとgithubは`0.1.8`. `conda cloud`にあるのは`0.1.0`. 
最新版を使いましょう. ちょっと勉強になった.