1. 程式人生 > 其它 >Electron整合Java服務端製作rpm包

Electron整合Java服務端製作rpm包

環境和原始檔

  • 淨室環境:

    淨室環境指的是沒有任何其他配置,剛剛安裝好的一個系統環境。
    淨室環境是為了避免一些依賴問題。
    可以通過虛擬機器或者實體機來獲得,這裡推薦使用虛擬機器,實體機相對成本更高。

  • 淨室環境系統:
    本次使用系統環境為 CentOS Linux release 7.9.2009 (Core)


  • 原始檔結構樹:

    demo資料夾為electron:build後輸出的資料夾(Linux環境下)
    其中scripts、server、res資料夾為後新增到demo目錄中

    demo/
    ├── chrome_100_percent.pak
    ├── chrome_200_percent.pak
    ├── chrome_crashpad_handler
    ├── chrome-sandbox
    ├── demo                --electron打包成的Linux可執行檔案
    ├── icudtl.dat
    ├── libEGL.so
    ├── libffmpeg.so
    ├── libGLESv2.so
    ├── libvk_swiftshader.so
    ├── libvulkan.so.1
    ├── LICENSE.electron.txt
    ├── LICENSES.chromium.html
    ├── locales
    ├── res                 --資原始檔夾
    │   └── Favs.ico        --圖示ico檔案
    ├── resources
    ├── resources.pak
    ├── scripts
    │   ├── demo.service    --Linux服務(後續有詳解)
    │   ├── rpminstall.sh   --安裝時需要執行的指令碼
    │   └── rpmuninstall.sh --解除安裝時需要執行的指令碼
    ├── server              --Java服務
    │   ├── demo.jar        --Java服務jar包
    │   └── jre             --jre執行環境
    ├── snapshot_blob.bin
    ├── swiftshader
    ├── v8_context_snapshot.bin
    └── vk_swiftshader_icd.json
    
    

Service服務配置

  • demo.service完整內容(使用打包到deb包中的jre執行jar包)

    如果不註冊成linux服務的話每次都需要執行Java -jar demo.jar 很麻煩,對使用者也十分的不友好,所以這裡將jar包服務註冊到linux服務中,並設定開機自啟。

    [Unit]
    Description=demo-server                                    
    
    [Service]
    Type=simple                                                 
    ExecStart=/usr/local/demo/server/jre/bin/java -jar /usr/local/demo/server/demo.jar
    
    [Install]
    WantedBy=multi-user.target
    
    
  • Service 區塊配置

    • [Unit] 區塊通常是配置檔案的第一個區塊,用來定義 Unit 的元資料,以及配置與其他 Unit 的關係。它的主要欄位如下。

    欄位 說明
    Description 簡短描述
    Documentation 文件地址
    Requires 當前 Unit 依賴的其他 Unit,如果它們沒有執行,當前 Unit 會啟動失敗
    Wants 與當前 Unit 配合的其他 Unit,如果它們沒有執行,當前 Unit 不會啟動失敗
    BindsTo 與Requires類似,它指定的 Unit 如果退出,會導致當前 Unit 停止執行
    Before 如果該欄位指定的 Unit 也要啟動,那麼必須在當前 Unit 之後啟動
    After 如果該欄位指定的 Unit 也要啟動,那麼必須在當前 Unit 之前啟動
    Conflicts 這裡指定的 Unit 不能與當前 Unit 同時執行
    Condition... 當前 Unit 執行必須滿足的條件,否則不會執行
    Assert... 當前 Unit 執行必須滿足的條件,否則會報啟動失敗
    • [Install] 通常是配置檔案的最後一個區塊,用來定義如何啟動,以及是否開機啟動。它的主要欄位如下。

    欄位 說明
    WantedBy 它的值是一個或多個 Target,當前 Unit 啟用時(enable)符號連結會放入/etc/systemd/system目錄下面以 Target 名 + .wants字尾構成的子目錄中
    RequiredBy 它的值是一個或多個 Target,當前 Unit 啟用時,符號連結會放入/etc/systemd/system目錄下面以 Target 名 + .required字尾構成的子目錄中
    Alias 當前 Unit 可用於啟動的別名
    Also 當前 Unit 啟用(enable)時,會被同時啟用的其他 Unit
    • [Service] 區塊用來 Service 的配置,只有 Service 型別的 Unit 才有這個區塊。它的主要欄位如下。

    欄位 說明
    Type 定義啟動時的程序行為。它有以下幾種值。
    Type=simple 預設值,執行ExecStart指定的命令,啟動主程序
    Type=forking 以 fork 方式從父程序建立子程序,建立後父程序會立即退出
    Type=oneshot 一次性程序,Systemd 會等當前服務退出,再繼續往下執行
    Type=dbus 當前服務通過D-Bus啟動
    Type=notify 當前服務啟動完畢,會通知Systemd,再繼續往下執行
    Type=idle 若有其他任務執行完畢,當前服務才會執行
    ExecStart 啟動當前服務的命令
    ExecStartPre 啟動當前服務之前執行的命令
    ExecStartPost 啟動當前服務之後執行的命令
    ExecReload 重啟當前服務時執行的命令
    ExecStop 停止當前服務時執行的命令
    ExecStopPost 停止當其服務之後執行的命令
    RestartSec 自動重啟當前服務間隔的秒數
    Restart 定義何種情況 Systemd 會自動重啟當前服務,可能的值包括always(總是重啟)、on-success、on-failure、on-abnormal、on-abort、on-watchdog
    TimeoutSec 定義 Systemd 停止當前服務之前等待的秒數
    Environment 指定環境變數

rpm打包

  • 環境準備

    RPM打包使用的是rpmbuild命令,這個命令來自rpm-build包,這個是必裝的。

    yum install rpm-build
    

    (推薦)也可以直接安裝rpmdevtools,這個工具還包含一些其他的工具,同時它依賴rpm-build,所以直接安裝的話會同時把rpm-build裝上。

    yum install rpmdevtools
    
  • 建立rpm工作空間

    RPM打包的時候需要編譯原始碼,還需要把編譯好的配置檔案啊二進位制命令檔案啊之類的東西按照安裝好的樣子放到合適的位置,還要根據需要對RPM的包進行測試,這些都需要先有一個“工作空間”。rpmbuild命令使用一套標準化的“工作空間”:

    rpmdev-setuptree
    

    rpmdev-setuptree這個命令就是安裝rpmdevtools帶來的。可以看到運行了這個命令之後,在$HOME家目錄下多了一個叫做rpmbuild的資料夾,裡邊內容如下:

    # cd $HOME
    # tree rpmbuild/
    
    rpmbuild/
    ├── BUILD
    ├── RPMS
    ├── SOURCES
    ├── SPECS
    └── SRPMS
    

    如果沒有安裝rpmdevtools的話,也可以手動通過命令mkdir建立這些資料夾

    mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
    
  • rpmbuild詳解

    預設位置 巨集程式碼 名稱 用途
    ~/rpmbuild/SPECS %_specdir Spec 檔案目錄 儲存 RPM 包配置(.spec)檔案
    ~/rpmbuild/SOURCES %_sourcedir 原始碼目錄儲存原始碼包(如 .tar 包)和所有 patch 補丁
    ~/rpmbuild/BUILD %_builddir 構建目錄原始碼包被解壓至此,並在該目錄的子目錄完成編譯
    ~/rpmbuild/BUILDROOT %_buildrootdir 最終安裝目錄 儲存 %install 階段安裝的檔案
    ~/rpmbuild/RPMS %_rpmdir 標準 RPM 包目錄 生成/儲存二進位制 RPM 包
    ~/rpmbuild/SRPMS %_srcrpmdir 原始碼 RPM 包目錄 生成/儲存原始碼 RPM 包(SRPM)
  • 配置rpmbuild

    由於本次打包是有electron構建好的專案,這裡不需要通過原始碼再進行構建,所以我們只需要BUILDROOT(最終安裝目錄,也就是想要將專案安裝到的目錄)和SPECS(配置)兩個路徑,取餘不用管。

    由於工具沒有自動生成BUILDROOT,所以這裡需要手動建立BUILDROOT資料夾

    mkdir $HOME/rpmbuild/BUILDROOT
    
    • 構建SPECS

    在SPECS裡新建一個demo.spec

     vi $HOME/SPECS/demo.spec
    

    demo.spec內容:

    # rpmrebuild autogenerated specfile
    
    BuildArch:     x86_64
    Name:          demo
    Version:       1.0.0
    Release:       1%{?dist}
    License:       GPL
    Summary:       This is Demo
    
    
    %description
    demo for linux
    %files
    %post -p /bin/sh
    bash /usr/local/demo/scripts/rpminstall.sh
    %preun -p /bin/sh
    bash /usr/local/demo/scripts/rpmuninstall.sh
    %changelog
    

    編輯完儲存


    • spec詳解

    欄位 說明
    Name 軟體包的名稱,後面可使用%{name}的方式引用
    Summary 軟體包的內容概要
    Version 軟體的實際版本號,例如:1.0.1等,後面可使用%{version}引用
    Release 釋出序列號,例如:1linuxing等,標明第幾次打包,後面可使用%{release}引用
    Group 軟體分組,建議使用標準分組
    License 軟體授權方式,通常就是GPL
    Source 原始碼包,可以帶多個用Source1、Source2等源,後面也可以用%{source1}、%{source2}引用
    BuildRoot 這個是安裝或編譯時使用的“虛擬目錄”,考慮到多使用者的環境,一般定義為:%{_tmppath}/%{name}-%{version}-%{release}-root或%{_tmppath}/%{name}-%{version}-%{release}-buildroot-%(%{__id_u} -n}該引數非常重要,因為在生成rpm的過程中,執行make install時就會把軟體安裝到上述的路徑中,在打包的時候,同樣依賴“虛擬目錄”為“根目錄”進行操作。後面可使用$RPM_BUILD_ROOT 方式引用。
    URL 軟體的主頁
    Vendor 發行商或打包組織的資訊,例如RedFlag Co,Ltd
    Disstribution 發行版標識
    Patch 補丁原始碼,可使用Patch1、Patch2等標識多個補丁,使用%patch0或%{patch0}引用
    Prefix %{_prefix} 這個主要是為了解決今後安裝rpm包時,並不一定把軟體安裝到rpm中打包的目錄的情況。這樣,必須在這裡定義該標識,並在編寫%install指令碼的時候引用,才能實現rpm安裝時重新指定位置的功能
    Prefix %{_sysconfdir} 這個原因和上面的一樣,但由於%{_prefix}指/usr,而對於其他的檔案,例如/etc下的配置檔案,則需要用%{_sysconfdir}標識
    Build Arch 指編譯的目標處理器架構,noarch標識不指定,但通常都是以/usr/lib/rpm/marcros中的內容為預設值
    Requires 該rpm包所依賴的軟體包名稱,可以用>=或<=表示大於或小於某一特定版本,例如:libpng-devel >= 1.0.20 zlib ※“>=”號兩邊需用空格隔開,而不同軟體名稱也用空格分開還有例如PreReq、Requires(pre)、Requires(post)、Requires(preun)、Requires(postun)、BuildRequires等都是針對不同階段的依賴指定
    Provides 指明本軟體一些特定的功能,以便其他rpm識別
    Packager 打包者的資訊
    %description 軟體的詳細說明

    • spec指令碼

    欄位 說明
    %prep 預處理指令碼
    %setup -n %{name}-%{version} 把原始碼包解壓並放好通常是從/usr/src/asianux/SOURCES裡的包解壓到/usr/src/asianux/BUILD/%{name}-%{version}中。一般用%setup -c就可以了,但有兩種情況:一就是同時編譯多個原始碼包,二就是原始碼的tar包的名稱與解壓出來的目錄不一致,此時,就需要使用-n引數指定一下了。
    %patch 打補丁通常補丁都會一起在原始碼tar.gz包中,或放到SOURCES目錄下。一般引數為:%patch -p1 使用前面定義的Patch補丁進行,-p1是忽略patch的第一層目錄
    %Patch2 -p1 -b xxx.patch 打上指定的補丁,-b是指生成備份檔案
    %setup 不加任何選項,僅將軟體包開啟。
    %setup -n newdir 將軟體包解壓在newdir目錄。
    %setup -c 解壓縮之前先產生目錄。
    %setup -b num 將第num個source檔案解壓縮。
    %setup -T 不使用default的解壓縮操作。
    %setup -T -b 0 將第0個原始碼檔案解壓縮。
    %setup -c -n newdir 指定目錄名稱newdir,並在此目錄產生rpm套件。
    %patch 最簡單的補丁方式,自動指定patch level。
    %patch 0 使用第0個補丁檔案,相當於%patch ?p 0。
    %patch -s 不顯示打補丁時的資訊。
    %patch -T 將所有打補丁時產生的輸出檔案刪除。
    %configure 這個不是關鍵字,而是rpm定義的標準巨集命令。意思是執行原始碼的configure配置在/usr/src/asianux/BUILD/%{name}-%{version}目錄中進行 ,使用標準寫法,會引用/usr/lib/rpm/marcros中定義的引數。另一種不標準的寫法是,可參考原始碼中的引數自定義,例如:CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{_prefix}
    %build 開始構建包在/usr/src/asianux/BUILD/%{name}-%{version}目錄中進行make的工作 ,常見寫法:make %{?_smp_mflags} OPTIMIZE="%{optflags}"都是一些優化引數,定義在/usr/lib/rpm/marcros中
    %install 開始把軟體安裝到虛擬的根目錄中在/usr/src/asianux/BUILD/%{name}-%{version}目錄中進行make install的操作。這個很重要,因為如果這裡的路徑不對的話,則下面%file中尋找檔案的時候就會失敗。 常見內容有:
    %makeinstall 這不是關鍵字,而是rpm定義的標準巨集命令。也可以使用非標準寫法:make DESTDIR=$RPM_BUILD_ROOT install或make prefix=$RPM_BUILD_ROOT install,需要說明的是,這裡的%install主要就是為了後面的%file服務的。所以,還可以使用常規的系統命令:install -d $RPM_BUILD_ROOT/ ;cp -a * $RPM_BUILD_ROOT/
    %clean 清理臨時檔案通常內容為:[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf "$RPM_BUILD_ROOT" ;rm -rf $RPM_BUILD_DIR/%{name}-%{version}※注意區分$RPM_BUILD_ROOT和$RPM_BUILD_DIR:$RPM_BUILD_ROOT是指開頭定義的BuildRoot,而$RPM_BUILD_DIR通常就是指/usr/src/asianux/BUILD,其中,前面的才是%file需要的。
    %pre rpm 安裝前執行的指令碼
    %post rpm 安裝後執行的指令碼
    %preun rpm 解除安裝前執行的指令碼
    %postun rpm 解除安裝後執行的指令碼
    %files 定義那些檔案或目錄會放入rpm中這裡會在虛擬根目錄下進行,千萬不要寫絕對路徑,而應用巨集或變量表示相對路徑。 如果描述為目錄,表示目錄中除%exclude外的所有檔案。
    %defattr (-,root,root) 指定包裝檔案的屬性,分別是(mode,owner,group),-表示預設值,對文字檔案是0644,可執行檔案是0755
    %exclude 列出不想打包到rpm中的檔案※小心,如果%exclude指定的檔案不存在,也會出錯的。
    %changelog 變更日誌

    • 當前rpmbuild目錄樹

    rpmbuild
    ├── BUILD
    ├── BUILDROOT
    │   └── usr
    │       ├── local
    │       │   └── demo
    │       └── share
    │           └── applications
    │               └── demo.desktop
    ├── RPMS
    ├── SOURCES
    ├── SPECS
    │   └── demo.spec
    └── SRPMS
    
    

    • demo.desktop完整內容(程式圖示)

    [Desktop Entry]
    #StartupWMClass=demo
    Categories=Network;RemoteControl;
    Comment=This is demo
    Comment[zh_CN]=這是一個演示
    Exec=/usr/local/demo/demo
    GenericName=demo
    GenericName[zh_CN]=演示程式
    Icon=/usr/local/demo/res/Favs.ico
    Name=demo
    Name[zh_CN]=演示
    StartupNotify=false
    Terminal=false
    Type=Application
    X-Deepin-Vendor=user-custom
    
    • desktop
      Desktop Entry檔案是Linux桌面系統中用於描述程式啟動配置資訊的檔案,它以.desktop為字尾名,相當於Windows系統下的桌面快捷方式。通常一個二進位制可執行程式是一個沒有後綴沒有圖示的檔案,不可以隨意移動。
      因此很多Linux發行版都提供了啟動器,便於集中管理應用程式。啟動器本質是一個位於/usr/share/applications/路徑下的目錄。啟動器目錄中存放著很多.desktop檔案,每個.desktop檔案都是一個應用程式的入口,並且.desktop檔案可以顯示圖示,對使用者更加友好。

    • desktop 檔案結構

    欄位 是否必選 說明
    Version 該數值指定了當前 Desktop Entry 檔案所遵循的 Desktop Entry 檔案標準版本
    Name 應用程式名稱
    GenericName 應用程式的通用名稱
    Comment 描述
    Type "Type"定義了Desktop Entry檔案的型別。常見的"Type"數值是"Application"和"Link"。"Type = Application"表示當前Desktop Entry檔案指向了一個應用程式;而"Type = Link"表示當前Desktop Entry檔案指向了一個URL (Uniform Resource Locator)。
    Exec "Exec"只有Type=Application才有效,"Exec"的數值定義了啟動指定應用程式所要執行的命令,在此命令是可以帶引數的
    URL "URL"只有Type=Link才有效。"URL"的數值定義了該Desktop Entry檔案指向的URL
    Icon "Icon"的數值是以絕對路徑的格式給出,圖示的絕對路徑。
    StartupNotify 布林值,只有Type=Application才有效,如果為true,則已知應用程式在使用DESKTOP_STARTUP_ID環境變數集啟動時將傳送“remove”訊息。
    Terminal 布林值,只有Type=Application才有效,相關應用程式(即關鍵字"Exec"的數值)是否需要在終端視窗中執行.
    Categories 只有Type=Application才有效,程式在選單中顯示的類別,network:網路應用;Chat:社交溝通;Audio:音樂欣賞;Video:視訊播放;Graphics:圖形影象;Office:辦公學習;Translation:閱讀翻譯;Development:程式設計開發;Utility:系統管理;

  • 開始試著打包


    在 rpmbuild/SPECS目錄中執行以下命令

    rpmbuild -bb demo.spec
    

    此時會報錯

    [root@localhost SPECS]# rpmbuild -bb demo.spec 
    處理檔案:demo-1.0.0-1.el7.x86_64
    Provides: demo = 1.0.0-1.el7 demo(x86-64) = 1.0.0-1.el7
    Requires(interp): /bin/sh /bin/sh
    Requires(rpmlib): rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1 rpmlib(CompressedFileNames) <= 3.0.4-1
    Requires(post): /bin/sh
    Requires(preun): /bin/sh
    檢查未打包檔案:/usr/lib/rpm/check-files /root/rpmbuild/BUILDROOT/demo-1.0.0-1.el7.x86_64
    寫道:/root/rpmbuild/RPMS/x86_64/demo-1.0.0-1.el7.x86_64.rpm
    執行(%clean): /bin/sh -e /var/tmp/rpm-tmp.uPYNbL
    + umask 022
    + cd /root/rpmbuild/BUILD
    + /usr/bin/rm -rf /root/rpmbuild/BUILDROOT/demo-1.0.0-1.el7.x86_64
    + exit 0
    
    

    這部其實主要是路徑問題,沒有相應的路徑/root/rpmbuild/BUILDROOT/demo-1.0.0-1.el7.x86_64, 建立這個路徑即可,然後將當前BUILDROOT/user 放到建立的路徑下即可。

    # mkdir $HOME/rpmbuild/BUILDROOT/demo-1.0.0-1.el7.x86_64
    # mv $HOME/rpmbuild/BUILDROOT/usr $HOME/rpmbuild/BUILDROOT/demo-1.0.0-1.el7.x86_64
    

    再次嘗試打包

    [root@localhost SPECS]# rpmbuild -bb demo.spec 
    處理檔案:demo-1.0.0-1.el7.x86_64
    Provides: demo = 1.0.0-1.el7 demo(x86-64) = 1.0.0-1.el7
    Requires(interp): /bin/sh /bin/sh
    Requires(rpmlib): rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1 rpmlib(CompressedFileNames) <= 3.0.4-1
    Requires(post): /bin/sh /bin/sh
    Requires(preun): /bin/sh /bin/sh
    檢查未打包檔案:/usr/lib/rpm/check-files /root/rpmbuild/BUILDROOT/demo-1.0.0-1.el7.x86_64
    錯誤:發現已安裝(但未打包的)檔案:
       /usr/local/demo/LICENSE.electron.txt
       /usr/local/demo/LICENSES.chromium.html
       /usr/local/demo/chrome-sandbox
       /usr/local/demo/chrome_100_percent.pak
       /usr/local/demo/chrome_200_percent.pak
       /usr/local/demo/chrome_crashpad_handler
                		.
                		.
                		.
    

    還是報錯,此報錯就是demo.spec中%files下沒有將要打包的檔案新增進去,修改demo.spec檔案。
    完整demo.spec檔案:

    展開檢視
    
    
    # rpmrebuild autogenerated specfile
    
    BuildArch:     x86_64
    Name:          demo
    Version:       1.0.0
    Release:       1%{?dist}
    License:       GPL
    Summary:       This is Demo
    
    Requires:      /bin/sh  
    Requires:      /bin/sh  
    
    %description
    demo for linux
    %files
    %attr(0755, root, root) "/usr/share/applications/demo.desktop"
    %dir %attr(0755, root, root) "/usr/local/demo"
    %attr(4755, root, root) "/usr/local/demo/chrome-sandbox"
    %attr(0755, root, root) "/usr/local/demo/LICENSE.electron.txt"
    %attr(0755, root, root) "/usr/local/demo/LICENSES.chromium.html"
    %attr(0755, root, root) "/usr/local/demo/chrome_100_percent.pak"
    %attr(0755, root, root) "/usr/local/demo/chrome_200_percent.pak"
    %attr(0755, root, root) "/usr/local/demo/chrome_crashpad_handler"
    %attr(0755, root, root) "/usr/local/demo/demo"
    %attr(0755, root, root) "/usr/local/demo/icudtl.dat"
    %attr(0755, root, root) "/usr/local/demo/libEGL.so"
    %attr(0755, root, root) "/usr/local/demo/libGLESv2.so"
    %attr(0755, root, root) "/usr/local/demo/libffmpeg.so"
    %attr(0755, root, root) "/usr/local/demo/libvk_swiftshader.so"
    %attr(0755, root, root) "/usr/local/demo/libvulkan.so.1"
    %attr(0755, root, root) "/usr/local/demo/locales/am.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/ar.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/bg.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/bn.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/ca.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/cs.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/da.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/de.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/el.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/en-GB.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/en-US.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/es-419.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/es.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/et.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/fa.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/fi.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/fil.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/fr.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/gu.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/he.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/hi.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/hr.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/hu.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/id.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/it.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/ja.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/kn.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/ko.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/lt.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/lv.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/ml.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/mr.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/ms.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/nb.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/nl.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/pl.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/pt-BR.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/pt-PT.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/ro.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/ru.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/sk.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/sl.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/sr.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/sv.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/sw.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/ta.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/te.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/th.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/tr.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/uk.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/vi.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/zh-CN.pak"
    %attr(0755, root, root) "/usr/local/demo/locales/zh-TW.pak"
    %attr(0755, root, root) "/usr/local/demo/resources.pak"
    %attr(0755, root, root) "/usr/local/demo/resources/app.asar"
    %attr(0755, root, root) "/usr/local/demo/scripts/demo.service"
    %attr(0755, root, root) "/usr/local/demo/scripts/rpminstall.sh"
    %attr(0755, root, root) "/usr/local/demo/scripts/rpmuninstall.sh"
    %attr(0755, root, root) "/usr/local/demo/server/demo.jar"
    %attr(0755, root, root) "/usr/local/demo/server/jre/ADDITIONAL_LICENSE_INFO"
    %attr(0755, root, root) "/usr/local/demo/server/jre/ASSEMBLY_EXCEPTION"
    %attr(0755, root, root) "/usr/local/demo/server/jre/LICENSE"
    %attr(0755, root, root) "/usr/local/demo/server/jre/THIRD_PARTY_README"
    %attr(0755, root, root) "/usr/local/demo/server/jre/bin/java"
    %attr(0755, root, root) "/usr/local/demo/server/jre/bin/jjs"
    %attr(0755, root, root) "/usr/local/demo/server/jre/bin/keytool"
    %attr(0755, root, root) "/usr/local/demo/server/jre/bin/orbd"
    %attr(0755, root, root) "/usr/local/demo/server/jre/bin/pack200"
    %attr(0755, root, root) "/usr/local/demo/server/jre/bin/policytool"
    %attr(0755, root, root) "/usr/local/demo/server/jre/bin/rmid"
    %attr(0755, root, root) "/usr/local/demo/server/jre/bin/rmiregistry"
    %attr(0755, root, root) "/usr/local/demo/server/jre/bin/servertool"
    %attr(0755, root, root) "/usr/local/demo/server/jre/bin/tnameserv"
    %attr(0755, root, root) "/usr/local/demo/server/jre/bin/unpack200"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/jli/libjli.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/jli/libjli.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/jvm.cfg"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libattach.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libattach.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libawt.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libawt.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libawt_headless.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libawt_headless.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libawt_xawt.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libawt_xawt.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libdt_socket.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libdt_socket.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libfontmanager.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libfontmanager.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libhprof.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libhprof.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libinstrument.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libinstrument.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libj2gss.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libj2gss.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libj2pcsc.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libj2pcsc.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libj2pkcs11.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libj2pkcs11.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libjaas_unix.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libjaas_unix.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libjava.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libjava.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libjava_crw_demo.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libjava_crw_demo.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libjawt.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libjawt.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libjdwp.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libjdwp.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libjpeg.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libjpeg.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libjsdt.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libjsdt.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libjsig.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libjsig.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libjsound.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libjsound.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libjsoundalsa.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libjsoundalsa.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/liblcms.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/liblcms.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libmanagement.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libmanagement.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libmlib_image.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libmlib_image.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libnet.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libnet.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libnio.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libnio.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libnpt.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libnpt.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libsaproc.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libsaproc.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libsctp.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libsctp.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libsplashscreen.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libsplashscreen.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libsunec.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libsunec.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libunpack.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libunpack.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libverify.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libverify.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libzip.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/libzip.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/server/Xusage.txt"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/server/libjsig.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/server/libjsig.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/server/libjvm.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/amd64/server/libjvm.so"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/calendars.properties"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/charsets.jar"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/classlist"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/cmm/CIEXYZ.pf"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/cmm/GRAY.pf"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/cmm/LINEAR_RGB.pf"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/cmm/PYCC.pf"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/cmm/sRGB.pf"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/content-types.properties"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/currency.data"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/ext/cldrdata.jar"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/ext/dnsns.jar"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/ext/localedata.jar"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/ext/meta-index"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/ext/nashorn.jar"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/ext/sunec.jar"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/ext/sunjce_provider.jar"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/ext/sunpkcs11.jar"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/ext/zipfs.jar"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/flavormap.properties"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/hijrah-config-umalqura.properties"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/images/cursors/cursors.properties"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/images/cursors/invalid32x32.gif"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/images/cursors/motif_CopyDrop32x32.gif"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/images/cursors/motif_CopyNoDrop32x32.gif"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/images/cursors/motif_LinkDrop32x32.gif"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/images/cursors/motif_LinkNoDrop32x32.gif"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/images/cursors/motif_MoveDrop32x32.gif"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/images/cursors/motif_MoveNoDrop32x32.gif"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/jce.jar"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/jexec"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/jexec.diz"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/jsse.jar"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/jvm.hprof.txt"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/logging.properties"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/management-agent.jar"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/management/jmxremote.access"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/management/jmxremote.password.template"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/management/management.properties"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/management/snmp.acl.template"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/meta-index"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/net.properties"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/psfont.properties.ja"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/psfontj2d.properties"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/resources.jar"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/rt.jar"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/security/US_export_policy.jar"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/security/blacklisted.certs"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/security/cacerts"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/security/java.policy"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/security/java.security"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/security/local_policy.jar"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/sound.properties"
    %attr(0755, root, root) "/usr/local/demo/server/jre/lib/tzdb.dat"
    %attr(0755, root, root) "/usr/local/demo/snapshot_blob.bin"
    %attr(0755, root, root) "/usr/local/demo/swiftshader/libEGL.so"
    %attr(0755, root, root) "/usr/local/demo/swiftshader/libGLESv2.so"
    %attr(0755, root, root) "/usr/local/demo/res/Favs.ico"
    %attr(0755, root, root) "/usr/local/demo/v8_context_snapshot.bin"
    %attr(0755, root, root) "/usr/local/demo/vk_swiftshader_icd.json"
    
    %post -p /bin/sh
    bash /usr/local/demo/scripts/rpminstall.sh
    %preun -p /bin/sh
    bash /usr/local/demo/scripts/rpmuninstall.sh
    %changelog
    

    修改還再次打包即可,打包後 $HOME/rpmbuild/RPMS下會生成相應的rpm包

  • 補充:


    • 檔案比較運算子

    命令 說明 例子/備註
    -e filename 如果 filename存在,則為真 [ -e /var/log/syslog ]
    -d filename 如果 filename為目錄,則為真 [ -d /tmp/mydir ]
    -f filename 如果 filename為常規檔案,則為真 [ -f /usr/bin/grep ]
    -L filename 如果 filename為符號連結,則為真 [ -L /usr/bin/grep ]
    -r filename 如果 filename可讀,則為真 [ -r /var/log/syslog ]
    -w filename 如果 filename可寫,則為真 [ -w /var/mytmp.txt ]
    -x filename 如果 filename可執行,則為真 [ -x /usr/bin/grep ]
    filename1-nt filename2 如果 filename1比 filename2新,則為真 [ /tmp/install/etc/services -nt /etc/services ]
    filename1-ot filename2 如果 filename1比 filename2舊,則為真 [ /boot/bzImage -ot arch/i386/boot/bzImage ]

    • 字串比較運算子 (請注意引號的使用,這是防止空格擾亂程式碼的好方法)

    命令 說明 例子/備註
    -z string 如果 string長度為零,則為真 [ -z "$myvar" ]
    -n string 如果 string長度非零,則為真 [ -n "$myvar" ]
    string1= string2 如果 string1與 string2相同,則為真 [ "$myvar" = "one two three" ]
    string1!= string2 如果 string1與 string2不同,則為真 [ "$myvar" != "one two three" ]

    • 算術比較運算子

    命令 說明 例子/備註
    num1-eq num2 等於 [ 3 -eq $mynum ]
    num1-ne num2 不等於 [ 3 -ne $mynum ]
    num1-lt num2 小於 [ 3 -lt $mynum ]
    num1-le num2 小於或等於 [ 3 -le $mynum ]
    num1-gt num2 大於 [ 3 -gt $mynum ]
    num1-ge num2 大於或等於 [ 3 -ge $mynum ]