執行 Python 程式

Loading

測試環境為 CentOS 8 x86_64 (虛擬機)

需先安裝 Python + pip – https://benjr.tw/104226

要執行 python 程式 ( 範例為透過 print 函數列印出 Hello ).

Python Interpreter

  • Python shell
    可以透過 Python 的 Shell 來打指令並立即看到結果.

    [root@localhost ~]# python3
    Python 3.6.8 (default, Jan 25 2023, 15:03:30)
    [GCC 8.5.0 20210514 (Red Hat 8.5.0-18)] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> print ('Hello')
    Hello
    >>>
    [1]+  Stopped                 python3
    
  • Python script
    或是透過編輯器把 Python script 寫成文字檔 ( .py ) 再透過 Python 直譯器來執行.

    [root@localhost ~]# vim hello.py
    print ('Hello')
    

    執行 Python 程式.

    [root@localhost ~]# python3 hello.py 
    Hello
    

執行檔

可以將 Python 程式打包成執行檔來使用,需透過 pip 安裝 pyinstaller 套件.

[root@localhost ~]# pip install pyinstaller

將剛剛的 hello.py 編譯成執行黨.

[root@localhost ~]# cat hello.py
print ('Hello')
[root@localhost ~]# pyinstaller hello.py
53 INFO: PyInstaller: 4.10
53 INFO: Python: 3.6.8
54 INFO: Platform: Linux-4.18.0-486.el8.x86_64-x86_64-with-centos-8
54 INFO: wrote /root/hello.spec
58 INFO: UPX is not available.
60 INFO: Extending PYTHONPATH with paths
['/root']
218 INFO: checking Analysis
219 INFO: Building Analysis because Analysis-00.toc is non existent
219 INFO: Initializing module dependency graph...
220 INFO: Caching module graph hooks...
227 INFO: Analyzing base_library.zip ...
2556 INFO: Caching module dependency graph...
2648 INFO: running Analysis Analysis-00.toc
2688 INFO: Analyzing /root/hello.py
2691 INFO: Processing module hooks...
2692 INFO: Loading module hook 'hook-difflib.py' from '/usr/local/lib/python3.6/site-packages/PyInstaller/hooks'...
2694 INFO: Loading module hook 'hook-encodings.py' from '/usr/local/lib/python3.6/site-packages/PyInstaller/hooks'...
2762 INFO: Loading module hook 'hook-heapq.py' from '/usr/local/lib/python3.6/site-packages/PyInstaller/hooks'...
2764 INFO: Loading module hook 'hook-pickle.py' from '/usr/local/lib/python3.6/site-packages/PyInstaller/hooks'...
2765 INFO: Loading module hook 'hook-xml.py' from '/usr/local/lib/python3.6/site-packages/PyInstaller/hooks'...
2979 INFO: Looking for ctypes DLLs
2980 INFO: Analyzing run-time hooks ...
2982 INFO: Including run-time hook '/usr/local/lib/python3.6/site-packages/PyInstaller/hooks/rthooks/pyi_rth_subprocess.py'
2983 INFO: Including run-time hook '/usr/local/lib/python3.6/site-packages/PyInstaller/hooks/rthooks/pyi_rth_pkgutil.py'
2986 INFO: Including run-time hook '/usr/local/lib/python3.6/site-packages/PyInstaller/hooks/rthooks/pyi_rth_inspect.py'
2990 INFO: Looking for dynamic libraries
3403 INFO: Looking for eggs
3403 INFO: Using Python library /lib64/libpython3.6m.so.1.0
3407 INFO: Warnings written to /root/build/hello/warn-hello.txt
3423 INFO: Graph cross-reference written to /root/build/hello/xref-hello.html
3431 INFO: checking PYZ
3431 INFO: Building PYZ because PYZ-00.toc is non existent
3431 INFO: Building PYZ (ZlibArchive) /root/build/hello/PYZ-00.pyz
3666 INFO: Building PYZ (ZlibArchive) /root/build/hello/PYZ-00.pyz completed successfully.
3668 INFO: checking PKG
3668 INFO: Building PKG because PKG-00.toc is non existent
3668 INFO: Building PKG (CArchive) hello.pkg
3688 INFO: Building PKG (CArchive) hello.pkg completed successfully.
3689 INFO: Bootloader /usr/local/lib/python3.6/site-packages/PyInstaller/bootloader/Linux-64bit-intel/run
3689 INFO: checking EXE
3689 INFO: Building EXE because EXE-00.toc is non existent
3690 INFO: Building EXE from EXE-00.toc
3690 INFO: Copying bootloader EXE to /root/build/hello/hello
3690 INFO: Appending PKG archive to custom ELF section in EXE
3709 INFO: Building EXE from EXE-00.toc completed successfully.
3711 INFO: checking COLLECT
3711 INFO: Building COLLECT because COLLECT-00.toc is non existent
3711 INFO: Building COLLECT COLLECT-00.toc
3749 INFO: Building COLLECT COLLECT-00.toc completed successfully.

會產生以下檔案/資料夾.

  • *.spec 檔案
    [root@localhost ~]# ll *.spec
    -rw-r--r-- 1 root root 1120 Sep 27 20:06 hello.spec
    
    [root@localhost ~]# cat hello.spec
    # -*- mode: python ; coding: utf-8 -*-
    
    
    block_cipher = None
    
    
    a = Analysis(['hello.py'],
                 pathex=[],
                 binaries=[],
                 datas=[],
                 hiddenimports=[],
                 hookspath=[],
                 hooksconfig={},
                 runtime_hooks=[],
                 excludes=[],
                 win_no_prefer_redirects=False,
                 win_private_assemblies=False,
                 cipher=block_cipher,
                 noarchive=False)
    pyz = PYZ(a.pure, a.zipped_data,
                 cipher=block_cipher)
    
    exe = EXE(pyz,
              a.scripts,
              [],
              exclude_binaries=True,
              name='hello',
              debug=False,
              bootloader_ignore_signals=False,
              strip=False,
              upx=True,
              console=True,
              disable_windowed_traceback=False,
              target_arch=None,
              codesign_identity=None,
              entitlements_file=None )
    coll = COLLECT(exe,
                   a.binaries,
                   a.zipfiles,
                   a.datas,
                   strip=False,
                   upx=True,
                   upx_exclude=[],
                   name='hello')
    
  • build 資料夾
    [root@localhost ~]# ll build/
    total 4
    drwxr-xr-x 2 root root 4096 Sep 27 20:06 hello
    
    [root@localhost ~]# ll build/hello/
    total 4528
    -rw-r--r-- 1 root root   14902 Sep 28 01:48 Analysis-00.toc
    -rw-r--r-- 1 root root  786943 Sep 28 01:48 base_library.zip
    -rw-r--r-- 1 root root    4895 Sep 28 01:52 COLLECT-00.toc
    -rw-r--r-- 1 root root    1724 Sep 28 01:52 EXE-00.toc
    -rwxr-xr-x 1 root root 1216648 Sep 28 01:52 hello
    -rw-r--r-- 1 root root 1164706 Sep 28 01:52 hello.pkg
    -rw-r--r-- 1 root root    1625 Sep 28 01:52 PKG-00.toc
    -rw-r--r-- 1 root root 1147459 Sep 28 01:48 PYZ-00.pyz
    -rw-r--r-- 1 root root    9329 Sep 28 01:48 PYZ-00.toc
    -rw-r--r-- 1 root root    2472 Sep 28 01:48 warn-hello.txt
    -rw-r--r-- 1 root root  254378 Sep 28 01:48 xref-hello.html
    
  • dist 資料夾
    [root@localhost ~]# ll dist
    total 4
    drwxr-xr-x 3 root root 4096 Sep 27 20:06 hello
    
    [root@localhost ~]# ll dist/hello/
    total 9892
    -rw-r--r--  1 root root  786943 Sep 27 20:06 base_library.zip
    -rwxr-xr-x  1 root root 1216648 Sep 27 20:06 hello
    -rwxr-xr-x. 1 root root   75328 May 10  2019 libbz2.so.1
    -rwxr-xr-x  1 root root 3083608 Feb 17  2023 libcrypto.so.1.1
    drwxr-xr-x  2 root root    4096 Sep 27 20:06 lib-dynload
    -rwxr-xr-x  1 root root  248216 Jan 10  2023 libexpat.so.1
    -rwxr-xr-x  1 root root  162192 Jun 27  2022 liblzma.so.5
    -rwxr-xr-x  1 root root 3286032 Jan 25  2023 libpython3.6m.so.1.0
    -rwxr-xr-x. 1 root root  338648 May 10  2019 libreadline.so.7
    -rwxr-xr-x  1 root root  615744 Feb 17  2023 libssl.so.1.1
    -rwxr-xr-x  1 root root  187496 May 31  2021 libtinfo.so.6
    -rwxr-xr-x  1 root root   99640 Dec  1  2022 libz.so.1
    

    執行檔 hello 在這個路徑下.

    [root@localhost ~]# dist/hello/hello
    Hello
    

遇過的問題

前面雖然編譯成執行檔,但是 so 檔案是分開儲存,在錯誤的路徑執行時就會發生錯誤.

[root@localhost ~]# cp dist/hello/hello ./
[root@localhost ~]# ./hello
[61168] Error loading Python lib '/root/libpython3.6m.so.1.0': dlopen: /root/libpython3.6m.so.1.0: cannot open shared object file: No such file or directory

我們可以再打包的時候使用參數 -F ( –onefile ) 將所有內容都包成單一檔案 (單一執行檔且檔案會相對大一些)

[root@localhost ~]# pyinstaller hello.py --onefile
45 INFO: PyInstaller: 4.10
45 INFO: Python: 3.6.8
46 INFO: Platform: Linux-4.18.0-486.el8.x86_64-x86_64-with-centos-8
47 INFO: wrote /root/hello.spec
51 INFO: UPX is not available.
53 INFO: Extending PYTHONPATH with paths
['/root']
215 INFO: checking Analysis
219 INFO: checking PYZ
221 INFO: checking PKG
221 INFO: Building because toc changed
222 INFO: Building PKG (CArchive) hello.pkg
2036 INFO: Building PKG (CArchive) hello.pkg completed successfully.
2039 INFO: Bootloader /usr/local/lib/python3.6/site-packages/PyInstaller/bootloader/Linux-64bit-intel/run
2039 INFO: checking EXE
2040 INFO: Building because name changed
2040 INFO: Building EXE from EXE-00.toc
WARNING: The output directory "/root/dist/hello" and ALL ITS CONTENTS will be REMOVED! Continue? (y/N)y
On your own risk, you can use the option `--noconfirm` to get rid of this question.
3828 INFO: Removing dir /root/dist/hello
3833 INFO: Copying bootloader EXE to /root/dist/hello
3834 INFO: Appending PKG archive to custom ELF section in EXE
3858 INFO: Building EXE from EXE-00.toc completed successfully.
[root@localhost ~]# cp dist/hello ./
cp: overwrite './hello'? y
[root@localhost ~]# ./hello
Hello
沒有解決問題,試試搜尋本站其他內容

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料