腳本解析器
PyInstaller的原理簡介
PyInstaller其實就是把python解析器和你自己的腳本打包成一個可執行的文件,和編譯成真正的機器碼完全是兩回事,所以千萬不要指
望成打包成一個可執行文件會提高運行效率,相反可能會降低運行效率,好處就是在運行者的機器上不用安裝python和你的腳本依賴的
庫。在Linux操作系統下,它主要用的binutil工具包裡面的ldd和objmp命令。
PyInstaller輸入你指定的的腳本,首先分析腳本所依賴的其他腳本,然後去查找,復制,把所有相關的腳本收集起來,包括Python解析
器,然後把這些文件放在一個目錄下,或者打包進一個可執行文件裡面。
可以直接發布輸出的整個文件夾裡面的文件,或者生成的可執行文件。你只需要告訴用戶,你的應用App是自我包含的,不需要安裝其他
包,或某個版本的Python,就可以直接運行了。
需要注意的是,PyInstaller打包的執行文件,只能在和打包機器系統同樣的環境下。也就是說,不具備可移植性,若需要在不同系統上運
行,就必須針對該平台進行打包。
pyinstaller將Python腳本打包成可執行程序,使在沒有Python環境的機器上運行
最新版是pyinstaller 3.1.1。支持python2.7和python3.3+。
可運行在Windows,Mac和Linux操作系統下。
但它不是跨編譯的,也就是說在Windows下用PyInstaller生成的exe只能運行在Windows下,在Linux下生成的只能運行在Linux下。
pyinstaller在windows下的安裝
使用命令pip install pyinstaller即可
在windows下,pyinstaller需要PyWin32的支持。當用pip安裝pyinstaller時未找到PyWin32,會自動安裝pypiwin32。
打包
打包的app里並不包含任何源碼,但將腳本的.pyc文件打包了。
基本語法:
pyinstaller options myscript.py
常用的可選參數如下:
--onefile 將結果打包成一個可執行文件
--onedir 將所有結果打包到一個文件夾中,該文件夾包括一個可執行文件和可執行文件執行時需要的依賴文件(默認)
--paths=DIR 設置導入路徑
--distpath=DIR 設置將打包的結果文件放置的路徑
--specpath=DIR 設置將spec文件放置的路徑
--windowed 使用windows子系統執行,不會打開命令行(只對windows有效)
--nowindowed 使用控制檯子系統執行(默認)(只對windows有效)
--icon=<FILE.ICO> 將file.ico添加為可執行文件的資源(只對windows有效
推薦學習《python教程》。
B. nginx和php-fpm之間是怎樣通信的
FastCGI原理
FastCGI是一個運用於Http Server和動態腳本語言間通信的介面,多數流行的Http Server都支持FastCGI,包括Apache、Nginx和lighttpd等。同時,FastCGI也被許多腳本語言支持,其中就有PHP。
FastCGI介面方式採用C/S結構,可以將HttP伺服器和腳本解析伺服器分開,同時在腳本解析伺服器上啟動一個或者多個腳本解析守護進程。當HttP伺服器每次遇到動態程序時,可以將其直接交付給FastCGI進程來執行,然後將得到的結果返回給客戶端。這種方式可以讓HttP伺服器專一地處理靜態請求或者將動態腳本伺服器的結果返回給客戶端,這在很大程度上提高了整個應用系統的性能。
Nginx+php-fpm實現原理
Nginx本身不會對PHP進行解析,終端對PHP頁面的請求將會被Nginx交給FastCGI進程監聽的IP地址及埠,由php-fpm作為動態解析伺服器處理,最後將處理結果再返回給nginx。其實,Nginx就是一個反向代理伺服器。Nginx通過反向代理功能將動態請求轉向後端php-fpm,從而實現對PHP的解析支持,這就是Nginx實現PHP動態解析的原理。
Nginx不支持對外部程序的直接調用或者解析,所有的外部程序(包括PHP)必須通過FastCGI介面來調用。FastCGI介面在Linux下是socket(這個socket可以是文件socket,也可以是ip socket)。為了調用CGI程序,還需要一個FastCGI的wrapper(wrapper可以理解為用於啟動另一個程序的程序),這個wrapper綁定在某個固定socket上,如埠或者文件socket。當Nginx將CGI請求發送給這個socket的時候,通過FastCGI介面,wrapper接收到請求,然後派生出一個新的線程,這個線程調用解釋器或者外部程序處理腳本並讀取返回數據;接著,wrapper再將返回的數據通過FastCGI介面,沿著固定的socket傳遞給Nginx;最後,Nginx將返回的數據發送給客戶端。
Nginx 簡單配置
location ~ \.php$ {
root /home/admin/web/nginx/html/;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/admin/web/nginx/html/$fastcgi_script_name;
include fastcgi_params;
}
C. 什麼是腳本解析器
首先要知道什麼是腳本,腳本是使用襪兆讓一種特定的描述性語言,依據一定的格式編寫的可執行文件,又稱作宏或批處理文件。
基本上就是程序,大多數指的是用文本編輯器編寫的文本代碼,然後用編譯器解告局析這些文本所要表達的意思和執行。就好象英語猜旅語句,可看作是腳本,翻譯的人就成了解析器。
D. 關於shell腳本#!的說明
Unix環境下的shell腳本通常都是#!/bin/sh開頭,那麼這句描述符究竟是什麼含義呢,我試圖解答這個問題。
首先#!必須出現在shell腳本的開頭位置,後面跟一個shell解析器,比如/bin/sh,或者/bin/bash,或者/usr/bin/ksh, 等等.
我們看到 a.sh使用的可執行程序是/bin/bash,這個/bin/bash是在a.sh文件裡面通過#!指定的。
a.out是一個可執行程序(ELF格式),它可以獨自運行,但是不能通過一個shell來運行。
#!實際上就是文件的魔數(magic number)
我們知道ELF格式為文件頭4個字元是".ELF",即(0x 7f 45 4c 46),而其實字元"#!"是shell腳本文件的魔數,即(0x 23 21),因為shell腳本是文本文件,#!就是兩個可讀的魔數字元。
這個魔數是干什麼用的呢?它是被操作系統exec系列函數使用的,exec函數需要載入一個文件時,它會讀取文件開頭魔數域,如果是".ELF",那麼就是一個ELF格式的可執行文件,如果是"#!"那麼就是一個腳本文件,然後再從"#!"後面繼續讀取腳本解析器,最後調用腳本解析器可執行程序,並把腳本本身作為參數傳遞給他。
注意
當前shell會讀取文件file的魔數
我也不清楚為什麼sh file格式不能支持file是二進制可執行程序,理論上sh還是可以去分析file的魔數,從而判斷file的類型,然後做區分處理。
https://en.wikipedia.org/wiki/Shebang_(Unix)