之前,我有寫過一篇Blog關於相關問題的解決方案,文章地址。最近,在Windows下配置python-nmap時,又遇到了一些問題。總結記錄一下。
關於”nmap program was not found in path”問題的解決辦法:
首先,我本機安裝了最新的Python-2.7.10和nmap-6.49BETA4。我還是打算用原來的python-nmap-0.2.4(官網最新版本已經到了python-nmap-0.4.0,關於它我們后續再說)。一切安裝都OK之后,在命令行下運行一下python-nmap-0.2.4下的example.py文件,得到了如下的結果:
我去,怎么還是這個問題呢?參考前一篇文章的配置,結果毫無作用呀!什么鬼?!我修改了好多地方的配置,還是不知道什么情況。好吧,我最后決定在Pycharm調試運行一下,看看到底是什么鬼。調試關鍵行如下圖所示:
從調試的結果看,應該是沒有問題的,nmap_path已經賦值了。(突然,我就覺得似乎第一篇文章關於python-nmap問題中,提供的增加nmap的本地路徑似乎也沒啥必要嘛?!)接着往下看,看它到底在哪里拋出異常了。找到了,如下圖所示:
這是什么?is_nmap_found默認為True,判斷是否正則匹配,不匹配則賦值False。看來是正則匹配出問題了。原來,python-nmap判斷是否安裝了nmap的方法就是在找到的nmap執行路徑下運行如下命令:
nmap -V
如果成功了,命令的返回值如下圖所示:
注意!這里有個坑!現在,采用https協議的網站越來越多了。從返回結果看,提供的nmap官網地址所采用的也是https協議。問題來了,我們看下python-nmap-0.2.4中的正則匹配:
regex = re.compile('Nmap version [0-9]*\.[0-9]*[^ ]* \( http://nmap\.org \)')
竟然判斷的是http協議有木有。這樣,無論怎么都匹配不上,所以得到的判斷條件總是False,最后也就拋出了異常,說找不到nmap。知道了這點就好辦了,稍微修改一下nmap.py中的正則表達式,修改后的正則表達式如下所示:
regex = re.compile('Nmap version [0-9]*\.[0-9]*[^ ]* \( http(|s)://.* \)')
刪除“C:\Python27\Lib\site-packages\nmap”下擴展名為pyc的文件,再次運行example.py,如下圖所示:
一切正常了。如果使用的老版本的python-nmap,而nmap安裝的又是最新版本的,就要注意”nmap -V”結果顯示中使用的是https協議,而python-nmap中正則表達式判斷的是http協議,稍微修改一下就OK了。
關於“close_fds is not supported on Windows platforms if you redirect stdin/stdout/stderr”問題的解決辦法:
既然官網放出了最新的python-nmap-0.4.0版本,那就試用一下最新版本吧。安裝一切OK之后,我來試一下,如下圖所示:
我去,這就是個什么鬼?問題不斷啊!冷靜一下,我們來查下Python 2.7.10 documentation,看看subprocess.Popen這個函數是干啥的。感覺比較重要的部分在這里:
If close_fds is true, all file descriptors except 0, 1 and 2 will be closed before the child process is executed. (Unix only). Or, on Windows, if close_fds is true then no handles will be inherited by the child process. Note that on Windows, you cannot set close_fds to true and also redirect the standard handles by setting stdin, stdout or stderr.
難道是默認值的問題,我們來修改一下默認值,從True改為False試試:
p = subprocess.Popen([nmap_path, '-V'], bufsize=10000, stdout=subprocess.PIPE, close_fds=False)
再次運行,看一下:
不報錯了,運行正常了。看來Linux下和Windows下還是有些不同的。所以在Windows下要使用python-nmap-0.4.0的話,記得把這個默認值改為False或者直接刪掉函數申明中的賦值就好(因為默認值就是False)。
好了,就這么多,如果對你有用,那是最好不過的了。