yum

軟件包管理

一.本章內容

            軟件運行環境

              軟件包基礎

rpm包管理

              yum管理

定製yum倉庫

編譯安裝

二.軟件運行和編譯

   ABI:ApplicationBinary Interface Windows與Linux不兼容

         ELF(Executableand Linkable Format)

         PE(PortableExecutable)

庫級別的虛擬化

         Linux: WINE       Windows: Cywin

API:ApplicationProgramming Interface

POSIX:Portable OS

程序源代碼 --> 預處理 --> 編譯 --> 彙編--> 鏈接

靜態編譯:.a

動態編譯:.so

  

靜態和動態鏈接

鏈接主要作用是把各個模塊之間相互引用的部分處理好,使得各個模塊之間能夠正確地銜接,分爲靜態鏈接和動態鏈接

靜態鏈接:

      把程序對應的依賴庫複製一份到包

                libxxx.a

                嵌入程序包

                升級難,需重新編譯

                佔用較多空間,遷移容易

動態鏈接

              只把依賴加做一個動態鏈接

                 libxxx.so

              連接指向”

                佔用較少空間,升級方便

wKiom1k9TRWCiz2UAACWpXjtBkc054.png-wh_50

C程序靜態鏈接:

wKiom1k9TWjwm-pVAAFb3i1HRQQ632.png-wh_50

 

JAVA程序運行:

wKiom1k9TZrg5SwyAACUwPmz5J4366.png-wh_50

Java 一次編譯到處運行,因爲是兩次編譯,先用java編譯器轉成字節碼,後綴是class文件(屬於中間代碼),可以再win用也可以再linux 用

wKioL1k9TcXy9ECLAAE_CvvlAow253.png-wh_50

開發語言

 系統級開發C    , C++

 應用級開發:java ,delphi ,Python ,go ,php ,perl ,ruby

一.包管 理器

  (1)二進制應用程序的組成部分二進制文件、庫文件、配置文件、幫助文件

    (2)程序包管理器

debian :deb 文件, dpkg 包管理器

redhat: rpm 文件, rpm 包管理器

rpm: Redhat Package Manager

RPM Package Manager

(3)包命名

3.1 源代碼

 name-VERSION.tar.gz|bz2|xz

例:linux -4.11.4.tar.xz 

  名字-(大版本號.次版本號.小版本號)-壓縮後綴

大版本號不變的話 架構是沒有什麼變化的,此版本號主要是一些小功能的微調,小版本號一般是用來調bug的。一般此版本號是偶數是穩定版,奇數版是測試版

VERSION: major.minor.release

3.2 rpm 包命名方式

name-VERSION-release.arch.rpm

例: :bash-4.2.46-19.el7.x86_64.rpm

    包名稱-版本號-編譯者加的版本號-CPU架構-後綴(cpu架構是noarch 就是不限制的意思)

VERSION: major.minor.release

release :release.OS

常見的arch:

x86:i386, i486, i586, i686

x86_64: x64, x86_64, amd64

powerpc: ppc

跟平臺無關:noarch

(4) : 分類 和 拆包

對一個稍微複雜點的程序,他會把不同類別的功能模塊分開放在各自的子包裏面

例:

Application-VERSION-ARCH.rpm: 主包

Application-devel-VERSION-ARCH.rpm  開發子包

Application-utils-VERSION-ARHC.rpm  其它子包

Application-libs-VERSION-ARHC.rpm  其它 子包

 包之間:可能存在依賴關係,甚至循環依賴

解決依賴包管理工具

yum :rpm 包管理器的前端工具(rpm不能解決包的依賴性的)

apt-get :deb 包管理器前端工具

zypper: suse 上的rpm 前端管理工具

dnf: Fedora 18+ rpm 包管理器前端管理工具 (dnf是yum的下一代)

(4)庫文件

    4.1 查看二進制程序所依賴的庫文件

ldd /PATH/TO/BINARY_FILE

例:ldd /bin/ls   查看ls的庫文件

wKiom1k9TgSRH763AADSj3-XeiE189.png-wh_50

    管理及查看本機裝載的庫文件: ldconfig

 顯示本機已經緩存的所有可用庫文件:/sbin/ldconfig–p

(如果庫文件損壞了,那麼依賴庫的命令都不能用,內部命令可以用)

 

4.2 名及文件路徑映射關係

配置文件:/etc/ld.so.conf,/etc/ld.so.conf.d/*.conf

(編譯安裝完成以後需要在配置文件裏面自己創建一個以.conf結尾的文件,文件裏面寫安裝的目錄,寫好以後需要用 ldconfig命令,讀下這個文件,把對應的庫文件加載到內存裏   ldconfig –p  可以查看已經加載到內存中的庫文件路徑信息)

緩存文件:/etc/ld.so.cache包管理器

(5)程序包管理器

功能將編譯好的應用程序的各組成文件打包一個或幾個程序包文件,從而方便快捷地實現程序包的安裝、卸載、查詢、升級和校驗等管理操作

  • 1 包文件組成 ( 每個包獨有)

RPM 包內的文件(各種各樣的文件列表)

RPM 的元數據,如名稱,版本,依賴性,描述等

安裝或卸載時運行的腳本(安裝前腳本,安裝後腳本 ,卸載前腳本,卸載後腳本)

2 、數據庫( 公共) :/var/lib/rpm(存放的安裝好的)

程序包名稱及版本

依賴關係

功能說明

包安裝後生成的各文件路徑及校驗碼信息

程序包的來源

 管理程序包的方式:

使用包管理器:rpm

使用前端工具:yum, dnf

獲取程序包的途徑:

(1)  系統發版的光盤或官方的服務器;

CentOS 鏡像:

https://www.centos.org/download/

http://mirrors.aliyun.com

http://mirrors.sohu.com

http://mirrors.163.com

md5sum  路徑 查看”haxi”值

(2)項目官方站點

(3)第三方組織:

Fedora-EPEL

Extra Packages for Enterprise LinuxRpmforge:RHEL推薦,包很全

搜索引擎 :

http://pkgs.org

http://rpmfind.net

http://rpm.pbone.net

https://sourceforge.net/

(4)自己製作  rpmbuild ,FPM 可以製作rpm包

  注意:第三方包建議要檢查其合法性

來源 合法性,

rpm 包管理

CentOS 系統上使用rpm 命令管理程序包:安裝、卸載、升級、查詢、校驗、數據庫維護

安裝

Rpm {-i|--install}[install-options] PACKAGE_FILE…

-v:verbose  可以顯示安裝過程

-vv: 更詳細的顯示安裝過程

-h:  以# 顯示程序包管理執行進度

rpm -ivhPACKAGE_FILE ...

例:安裝vsftpd 顯示安裝詳情並且顯示包執行進度

wKioL1k9TkHyBmfKAADXQh1Eeuk961.png-wh_50

 

rpm 包安裝

       [install-options]

--test:  測試安裝,但不真正 執行安裝,即dry run 模式

wKiom1k9Tp7zBpELAAAeJown5Zw200.png-wh_50 

--nodeps :忽略依賴關係

wKiom1k9U4_DVxY2AAAd_-XXX6I539.png-wh_50

--replacepkgs覆蓋安裝 替換整個包| replacefilesi

--replacefiles 替換文件  替換包裏的某些文件

wKioL1k9U62gm97hAAA_g9Ck55I937.png-wh_50

--nosignature:  不檢查來源合法性

--nodigest :不檢查包完整性

--noscripts :不執行 程序包腳本

--force q :強制安裝(只能在安裝升級的時候用,不能在卸載的時候用)於—replacepkgs 同樣效果

%pre: ; 安裝前腳本; --nopre

%post: ; 安裝後腳本; --nopost

%preun: ; 卸載前腳本; --nopreun

%postun:  卸載後腳本; --nopostun

包卸載

rpm {-e|--erase} [--allmatches] [--nodeps] [--

noscripts][--notriggers] [--test] PACKAGE_NAME ...

         --nodeps :忽略依賴關係

    -e 

--erase 

--allmatches:卸載所有 同名的包

--noscripts :卸載不運行腳本

--notriggers :不運行觸發器

--test : 測試卸載

例:卸載 vsftpd 

wKiom1k9U8-CyfxlAAAbCzg2vw0636.png-wh_50

卸載包的時候可以不寫路徑直接寫包名

 

 

rpm 包升級

升級:升級會刪除舊 版本

rpm {-U|--upgrade}[install-options]  PACKAGE_FILE ...

rpm {-F|--freshen}[install-options]  PACKAGE_FILE ...

upgrade :安裝有舊版程序包,則“升級”

如果不存在舊版程序包,則“安裝”

 

freshen :安裝有舊版程序包,則“升級”

如果不存在舊版程序包,則不執行升級操作

rpm -UvhPACKAGE_FILE ...

wKiom1k9U_PR4nBBAAAh43pMceY103.png-wh_50

rpm -FvhPACKAGE_FILE ...

--oldpackage:降級(實際上是新老版本共存)

wKiom1k9VBaQJrRPAAAdluPaK54445.png-wh_50

--force:強制安裝

升級注意項

  注意

(1)不要對內核做升級操作;Linux 支持多內核版本並存,因此,對直接安裝新版本內核

     如果安裝了兩個內核,需要選擇一個內核作爲默認啓動內核,/boot/rub/grub.conf

wKiom1k9VDezmQejAAHGz2xPyQ8046.png-wh_50

(2)  如果原程序包的配置文件安裝後曾被修改,升級時,新版本的提供的同一個配置文件並不會直接覆蓋老版本的配置文件,而把新版本的文件重命名(FILENAME.rpmnew) 後保留

包查詢

rpm {-q|--query} [select-options][query-options]

[select-options]

   -q: 查詢包是否安裝過了 不要寫錯否則就查不出來了

wKioL1k9VGHT9ScsAABcAY8NBp4616.png-wh_50 

判斷是包是否安裝

wKioL1k9VICTmwVjAABA0nP08cQ372.png-wh_50

-a:  所有包(支持模糊查找)

wKiom1k9WcGQKZYaAABB86LAbxw615.png-wh_50

wKiom1k9VL2jUeZKAABc2EiqQoQ435.png-wh_50

-f:  查看指定的文件由哪個程序包安裝生成(查看文件來自於哪個包)

wKiom1k9WXSSPfrxAABE-S2-bo8774.png-wh_50

-prpmfile :針對尚未安裝的程序包文件做查詢操作

P後面要跟文件名,不能是包名

wKioL1k9WZiR6UIbAAA5ka_mems219.png-wh_50

--whatprovidesCAPABILITY :查詢指定的 CAPABILITY

由哪個包所提供

--whatrequiresCAPABILITY :查詢指定的 CAPABILITY 被哪個包所依賴

rpm2cpio  包文件|cpio–itv 預覽包內文件

rpm2cpio  包文件|cpio–id “*.conf” 釋放包內文件

[query-options]

--changelog :查詢rpm 包的changelog

-c:  查詢程序的配置文件

wKioL1k9WdWxNWonAABB86LAbxw228.png-wh_50只列出配置文件

-d:  查詢程序的文檔

wKiom1k9WfWgTcg8AABJQOrSAuc134.png-wh_50 只列出文檔

-i: information 包的描述信息

如果查沒有安裝包的描述信息需要加“P”

wKioL1k9WhewwLwHAAA2Se7cEzs699.png-wh_50

-l:  查看指定的程序包安裝後生成的所有文件(不能查腳本文件)

wKiom1k9Wjfxut3gAAA8BYRXv5U887.png-wh_50

--scripts :程序包自帶的腳本

wKioL1k9WlrzayxtAABRK5HyLCs722.png-wh_50

--provides:  列出指定程序包所提供的CAPABILITY

-R:  查詢指定的程序包所依賴的CAPABILITY

常用查詢用法:

-qi PACKAGE, -qf FILE, -qc PACKAGE, -qlPACKAGE, -qd PACKAGE

-qpiPACKAGE_FILE, -qpl PACKAGE_FILE, ...

-qa

包校驗:

包在安裝時候會把我們在每個在磁盤生成的文件,這些文件的權限(大小,權限等),都放在數據庫裏面

rpm {-V|--verify} [select-options][verify-options]

 -v 可以查詢比對

wKiom1k9Wn_AZC50AACdOoe7sw4059.png-wh_50

wKioL1k9Wp6hzJWCAAApBiV5hu0552.png-wh_50查看所有的

S file Size differs    文件大小

M Modediffers (includes permissions and file type)

5 digest(formerly MD5 sum) differs   哈希值

D Device major/minornumber mismatch

LreadLink(2) path mismatch

U Userownership differs

G Groupownership differs

T mTimediffers   時間

Pcapabilities differ

包來源合法性驗正及完整性驗正

完整性驗正:SHA256

來源合法性驗正:RSA

公鑰加密

對稱加密:加密、解密使用同一密鑰

非對稱加密:密鑰是成對兒的

publickey:  公鑰,公開所有人

secret key:  私鑰,  不能公開

導入所需要公鑰

rpm -K|checksig rpmfile 檢查包的完整性和簽名

檢查包是否是合法來源,是否做過修改

wKiom1k9WsCwvdyEAAB48NFDQpE661.png-wh_50

1.正常情況剛裝好的系統檢查任何包顯示都是notok,是因爲先裝好的系統欠缺檢查的手段,欠缺檢查的文件

2.需要導入一個鑰匙,在光盤裏有一個祕鑰,需要導入下

wKiom1k9Wt3CqiwkAABj5okPvqQ950.png-wh_50

下圖爲祕鑰內容

wKioL1k9Wvvhj4zIAAZMVzjjD1o903.png-wh_50

然後執行導入祕鑰

wKiom1k9WyDSksXQAABRvj9fGV8572.png-wh_50

然後就可以正常查詢包

wKiom1k9W0XyEqPZAAB9IpDiNKY070.png-wh_50

 

rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

CentOS 7 發行版光盤提供:  RPM-GPG-KEY-CentOS-7

rpm -qa “gpg-pubkey*” 查詢裝好的祕鑰

wKioL1k9W2HA4eaYAACCjpQleWU380.png-wh_50

rpm  -qi  上面命令查出來的結果  就可以查詢安裝好的祕鑰內容

wKiom1k9W5Cg55i5AAKNjDA6IYY094.png-wh_50

卸載導入的祕鑰

wKioL1k9W63RXFacAABi-OyrCHM115.png-wh_50

安裝的時候有報錯需要先導入下祕鑰,然後在安裝

wKiom1k9W8uSqFXwAAEYlKx0yFw750.png-wh_50

注:裝好的操作系統 操作系統默認會把這個祕鑰放在磁盤上

wKioL1k9W-mwR9OwAADg-r8jWVw390.png-wh_50

rpm 數據庫

  數據庫重建:

/var/lib/rpm

rpm {--initdb|--rebuilddb}

initdb:  初始化

如果 事先不存在數據庫,則新建之

否則 ,不執行任何操作

rebuilddb :重建已 安裝的包頭的數據庫 索引目錄

yum

!以repodata的父目錄作爲yum 源的路徑 !

CentOS :  yum, dnf

YUM: Yellowdog UpdateModifier ,rpm 的前端程序,可解決軟件包相關依賴性,可在多個庫之間定位軟件包,up2date的替代工具

yum repository: yum repo ,存儲了衆多rpm 包,以及

包的相關的元數據文件(放置於特定目錄repodata 下)

文件服務器:

http://

https://

ftp://

本機 file:// 

yum 配置文件

 yum 客戶端配置文件:

/etc/yum.conf :爲所有倉庫提供公共配置

wKioL1k9XA6jPwHpAAHJqHuXJTU215.png-wh_50

/etc/yum.repos.d/*.repo:爲倉庫的指向提供配置

倉庫指向的定義:(只需要記下加點的 三項)

  • [repositoryID]   [ ]是固定格式不能加空格,中括號中的名字可以自定義

name=Somename for this repository (是一個描述,也可以不加,不加會有一個報警)

  • baseurl=url://path/to/repository/倉庫的路徑

enabled={1|0}  啓用或禁用

  • gpgcheck={1|0}檢查祕鑰(不寫這一行,默認是1)

gpgkey=URL祕鑰路徑

enablegroups={1|0}      啓用組

failovermethod={roundrobin|priority}(就是baseurl 可以寫很多個

roundrobin: : 意爲隨機挑選,默認值

priority:按順序訪問

cost= 默認爲1000   優先級

例如:

wKioL1k9XC7Qw9wYAAB3QOnX11Q113.png-wh_50

也可以直接寫入祕鑰地址 導入:wKiom1k9XFCAdh4XAAB2jdgvG0U067.png-wh_50

也可以在地址後面加上$releasever變量

wKiom1k9XHOzNHhCAAB1NaMPdcQ635.png-wh_50

 

yum 倉庫

yum 的repo 配置文件中可用的變量:

$releasever:  當前OS的發行版的主版本號

$arch:  平臺,i386,i486,i586,x86_64等等

$basearch :基礎平臺;i386, x86_64

$YUM0-$YUM9: 自定義變量

實例:

http://server/centos/$releasever/$basearch/

http://server/centos/7/x86_64

http://server/centos/6/i384

也可以禁用yum 倉庫 enableed=0

wKiom1k9XJCShvNsAADTksedbCE976.png-wh_50

yum源 源

  阿里雲 雲repo 文件:http://mirrors.aliyun.com/repo/

CentOS 系統yum源

阿里雲:https://mirrors.aliyun.com/centos/$releasever/os/x86_64/

教學 環境:http://172.16.0.1/cobbler/ks_mirror/$releasever/

Epel 的yum源:

阿里雲:https://mirrors.aliyun.com/epel/$releasever/x86_64

 教學環境:

http://172.16.0.1/fedora-epel/$releasever/x86_64/

 

yum-config-manager 自動生成.repo

 

生成172.16.0.1_cobbler_ks_mirror_CentOS-X-x86_64_.repo

yum-config-manager--add-repo=http://172.16.0.1/cobbler/ks_mirror/7/

wKioL1k9XK3ShCREAAGdcIaCXXk611.png-wh_50

 yum-config-manager --disable 倉庫名" 禁用倉庫

yum-config-manager --enable “倉庫名”

yum 命令

yum 命令的用法:

yum [options] [command] [package ...]

顯示倉庫列表:

yum repolist [all|enabled|disabled]

         所有|啓用 | 禁用

wKiom1k9XNDSUZFAAABD3-36t-k791.png-wh_50

Yum repolist all  可以顯示所有的yum倉庫(禁用,啓用)

wKiom1k9XO_Tmu4BAABcDeeZW_s791.png-wh_50

顯示程序包:

yum list  查看包列表

輸入 yum list 命令以後就會顯示yum 所有的包

 其中@anaconda 表示安裝操作系統時通過安裝操作系統安裝的包    其中顯示os7 表示可用包但是沒有裝    顯示installed 表示通過rpm 命令安裝的包

wKioL1k9XQ2BnClzAAEH-6KwoAU182.png-wh_50

yum list [all | glob_exp1] [glob_exp2] [...]

yum list {available|installed|updates} [glob_exp1]

   沒有裝過的|已經裝好的|更新的包

[...]

  安裝程序包:

yum install package1 [package2] [...]

例如:

wKiom1k9XSmTAK3LAABL5G92aCw243.png-wh_50

yum reinstall package1 [package2] [...] ( 重新安裝)

yum 命令

  升級程序包:

yum update [package1] [package2] [...]

yum downgrade package1 [package2] [...] ( 降級)

  檢查可用升級:

yum check-update

  卸載程序包:

yum remove | erase       package1 [package2] [...]

  查看程序包information: :

yum info [...]

  查看指定的特性( 可以是某文件) 是由哪個程序包所提供:

yum provides | whatprovides feature1 [feature2][...]

  清理本地緩存:

清除/var/cache/yum/$basearch/$releasever 緩存

yum clean [ packages | metadata |expire-cache |rpmdb | plugins | all ]

wKiom1k9XUrCwIHjAABKfV7Apdw017.png-wh_50

  構建緩存:

yum makecache

搜索:yumsearch string1 [string2] [...]

以指定的關鍵字搜索程序包名及summary 信息

wKiom1k9XWqDJGKoAABINbMnMmk268.png-wh_50

查看指定包所依賴的capabilities: :

yum deplist package1 [package2] [...]

 查看yum事務歷史:

yum history [info|list|packages-list|packages-info|

summary|addon-info|redo|undo|

rollback|new|sync|stats]

yum history

yum history info 6

yum history redo  可以重做

yum historyundo 6  取消歷史yum安裝(yum 卸載命令,卸載安裝包時不會卸載安裝時一起安裝的依賴包,所以可以用yumhistory 查看歷史安裝記錄 用歷史取消命令卸載安裝軟件可以一起把一起安裝的依賴包也給卸載掉。同樣也可以取消卸載

wKioL1k9XYej_i82AAHGNSVvg94303.png-wh_50

志 日誌 : :/var/log/yum.log

安裝及升級本地程序包:

yum localinstall rpmfile1 [rpmfile2] [...]

( 用install 替代)

yum localupdate rpmfile1 [rpmfile2] [...]

( 用update 替代)

包組管理的相關命令:

yum groupinstall group1 [group2] [...]

yum groupupdate group1 [group2] [...]

yum grouplist [hidden] [groupwildcard] [...]  列包組

wKiom1k9XaHBuJA7AAAzfbgM7i0257.png-wh_50

yum groupremove group1 [group2] [...]

yum groupinfo group1 [...]  查看包信息,沒有符號表示已經安裝到系統了,但是安裝時候不是通過包租安裝的,或許是通過系統安裝或者通過rpm,。“-”表示沒有安裝,但是也會通過包組安裝,因爲之前通過包組安裝過後又單獨卸載了,這種情況包組不會再次安裝“+”表示沒有安裝但會通過包組安裝

wKioL1k9Xbzz3PolAANtNiWq1NE187.png-wh_50

yum 的命令行選項:

--nogpgcheck :禁止進行gpg check

-y:  自動回答爲“yes”

-q :靜默模式

--disablerepo=repoidglob :臨時禁用此處指定的repo

--enablerepo=repoidglob :臨時啓用此處指定的repo

--noplugins

系統光盤yum 倉庫

系統安裝光盤作爲本地yum 倉庫:

(1)  掛載光盤至某目錄,例如/media/cdrom

# mount /dev/cdrom /media/cdrom

例:光盤掛在路徑爲/misc/cd/Packages

wKioL1k9XdqBtDWIAABXQsEPl_Q385.png-wh_50

那麼配置文件yum倉庫裏面寫的路徑是/misc/cd    因爲這個目錄下面有一個repodata.   Repodata的父目錄就可以做yum源的路徑

wKiom1k9XfiinCaTAABZrCEAm4g853.png-wh_50

(2)  創建配置文件

[CentOS7]

name=

baseurl=

gpgcheck=

enabled=

創建yum 倉庫:

createrepo [options] <directory>

程序包編譯

  程序包編譯安裝:

Application-VERSION-release.src.rpm -->  安裝後,使用rpmbuild 命令製作成二進制格式的rpm 包,而後再安裝

  源代碼--> 預處理--> 編譯--> 彙編-->鏈接--> 執行

  源代碼組織格式:

多文件:文件中的代碼之間,很可能存在跨文件依賴關係

C 、C++ :make  項目管理器

configure --> Makefile.in --> makefile

java:maven

編譯安裝

C 語言源代碼編譯安裝三步驟:

1 、./configure

(1)  通過選項傳遞參數,指定啓用特性、安裝路徑等;行時會參考用戶的指定以及makefile.in 文件生成makefile

(2)  檢查依賴到的外部環境,如依賴的軟件包

2 、make 根據makefile 文件,構建應用程序

3 、make install 複製文件到相應路徑

  開發工具:

autoconf:  生成configure腳本

automake :生成Makefile.in

  注意:安裝前查看INSTALL ,README

開源程序源代碼的獲取:

官方自建站點:

apache.org (ASF :Apache Software Foundation)

mariadb.org

...

代碼託管:

SourceForge.net

Github.com

code.google.com

c/c++ 編譯器: gcc (GNU C Complier)

 編譯C 源代碼:

準備:提供開發工具及開發環境

開發工具:make, gcc等 等

開發環境:開發庫,頭文件

glibc :標準庫

實現:通過“包組”提供開發組件

Development Tools

Server Platform Development

庫文件

查看二進制程序所依賴的庫文件:

ldd /PATH/TO/BINARY_FILE

wKiom1k9XhrCpmGtAABXA-RgZyU863.png-wh_50

管理及查看本機裝載的庫文件:

ldconfig

/sbin/ldconfig -p:  顯示本機已經緩存的所有可用庫文件

名及文件路徑映射關係:

配置文件:/etc/ld.so.conf, /etc/ld.so.conf.d/*.conf

緩存文件:/etc/ld.so.cache

 

 

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章