系统调用:任何一个主机,它对底层硬件实现抽象后所得到(输出)的接口 System call。
库:在操作系统之上附加的一段可共享的可用代码段,这一代码段被分成多个模块,每一个模块就叫一个库文件。
API:Application Programing Interface,。即遵循统一标准的可兼容的接口。若系统之间API互相兼容,则称为POSIX(Protable OS,可移植操作系统, 而IX是使得其命名风格与UNIX,Linux像似而随意添加的) API,可实现程序的跨系统运行。
注:1、32位的操作系统对应32位的库,64位的操作系统对应64位的库;64位的内核和程序必须运行在64位的CPU上,而32位的内核和程序可运行在32位和64位的CPU上。
2、库接口需要有一个规范,使得在不同操作系统上开发的应用程序的源代码可以能够在不同系统之间彼此交叉编译运行。
程序源代码(本质为包含文本信息的文本字符串) --> 预处理操作(如C的宏替换,变量声明的检测,检测数据是否溢出) --> 编译(编译后的代码称为目标代码(Object Code)) --> 汇编器执行编译操作将目标代码转换成机器代码(指令) --> 链接(编译完后指定程序需要使用的共享库文件的位置)
编译:
静态编译:编译时将程序需要的共享库复制一份到程序内部,不需要外部环境即可运行,但会使得程序的体积增大。
共享编译:调用/lib,/lib64下的.so文件。
ABI:Application Binary Interface,
因为Windows支持EXE格式的二进制文件,Linux支持ELF格式的二进制文件,所以程序转换为二进制程序后不兼容,因为其ABI不同,而且其对应的库文件的路径可能不同(Windows下C://...,Linux下/lib...)
解决不兼容问题方法:
1、库级别的虚拟化:
Linux:WINE
Windows:Cywin
缺陷:此类虚拟化产品受众较小;稳定性有待考证
2、应用程序级别的解决方案,在不同的操作系统提供一个写程序,调试程序,运行程序的应用程序(开发环境),在这个开发环境之上开发的程序即可实现跨平台。如Java的JVM。
程序开发级别:
操作系统级开发:面对硬件开发程序;
系统级开发:面对库调用和系统调用开发程序,如C,C++;
应用程序级开发:面对特定的应用程序专有的开发环境开发程序,如Java,Python,PHP,Perl,Ruby;
二进制应用程序的组成部分:
注:若程序只提供二进制文件但需要二次开发,则需要把开发库编译成二进制输出库给用户,并说明开发库如何调用、其中的函数有哪些、调用的名称、有哪些参数、参数种类、类型等信息等。
Debian:deb(程序包格式),dpt(包管理器)
Redhat:使用Perl语言仿照deb格式研发了RPM格式的包,rpm(包管理器)
rpm:Redhat Package Manager--->使用C语言重新研发了RPM:RPM is Package Manager(到今天为止成为主流)
Gento
ArchLinux
源代码命名格式:
name-VERSION.tar.gz(xz,gz2)
VERSION组成:major.minor.release 主版本号.次版本号.发行版
rpm包命名格式:
name-VERSION-release.ARCH.rpm
VERSION:major.minor.release(程序包的release)
release.ARCH:
release(rpm包的release)
release.os
常见的arch(硬件平台架构,iX86系列本质上没有什么区别,只是对于X数字越大,适用于更高的性能、更新的CPU、对CPU的性能发挥的越好,彼此之间是兼容的):
x86:i386,i486,i586,i686
x86_64:x64,x86_64,amd64(第一个64位平台的CPU是由AMD研发的)
powerpc:ppc
跟平台无关:noarch(如Java,Python的平台无关性程序(只依赖于运行环境),有时候C语言也可做成平台兼容)
例:zlib-1.2.7-13.el7.i686.rpm
引入一个问题:假设有一个程序testapp,它有28个功能,其中8个常用功能,20个不常用功能,那么如何进行打包呢?
此时可通过拆包解决。
如:
testapp-VERSION-ARCH.rpm:主包
testapp-devel-VERSION-ARCH.rpm:支包(子包,分包),依赖于主包
testapp-testing-VERSION-ARCH.rpm:支包(子包,分包),依赖于主包
由上例可知,包之间存在依赖关系;而如果考人工来管理包之间的依赖关系是非常不便的,因此引入程序包管理器的前端工具解决包之间依赖关系。
程序包管理器的前端工具:
程序包管理器的前端工具,用于实现对所有或某一个仓库中的所有程序包彼此之间的依赖关系做分析,并将它们抽取出来放入一个元数据文件中。将来使用这个仓库安装数据包时,它能够自动查找对应的元数据文件,并根据元数据文件获取到包之间的依赖关系。并且它还能到指定的仓库中(本地或互联网上的仓库),扮演一个ftp服务器的客户端工具的角色,下载的程序包缓存到本地安装完,安装完成后会将包清理掉(Android上的安装软件也是如此)。
yum:rpm包管理器的前端工具;
apt-get:deb包管理器的前端工具
zipper:Susa上rpm包管理器的前端管理工具
dnf:Fedora 22+ rpm包管理器的前端管理工具
YaST:Susa图形化管理工具(类似于控制面板)
查看二进制程序依赖的库文件:
ldd /PATH/TO/BINARY_FILE
如:
管理及查看本机装载的库文件:
ldconfig
/sbin/ldconfig -p #显示本机已经缓存的所有可用库文件名及文件路径缓存映射关系
一个应用程序启动时,向系统请求某库文件时,若此库文件已经转载进内存中,直接使用;若未装载到内存中,通过ldconfig -p查看缓存来获取库文件的位置,在读入到内存中。
可以通过重读来重新生成缓存,直接敲ldconfig重新读取并装载缓存:
配置文件为:/etc/ld.so.conf、/etc/ld.so.conf.d/*.conf
缓存文件为:/etc/ld.so.cache
功能:将编译好的应用程序的各组成文件打包成一个或多个程序包文件,从而方便而快捷的实现程序包管理的安装、卸载、查询、升级和校验等管理操作。
组成:
1、程序的组成清单:(每个包独有)
文件清单
安装或卸载时运行的脚本
2、数据库:(公共)
程序包的版本及名称
依赖关系
功能说明
安装生成的文件路径及校验码信息
管理程序包的方式:
使用包管理器:rpm
使用前端工具:yum、dnf
获取程序包的途径:
1、系统发行版的光盘或官方的服务器
CentOS镜像:
http://mirrors.aliyun.com
http://mirrors.sohu.com
http://mirrors.163.com
2、项目官方站点
3、第三方组织:
建议优先选择Fedora-EPEL(唯一可靠第三方来源,不加检测即可信任)
第三方提供者使用搜索引擎搜索即可
搜索引擎:(专门找rpm包的搜索引擎)
http://pkgs.org
http://rpmfind.net
http://rpm.pbone.net
4、自己制作
检查:无论从何处下载的任何程序包都需要检查其合法性(文件在传输过程中都有可能被篡改(经过别人路由时))
来源合法性;
程序包的完整性;
安装、卸载、升级、查询、校验、数据库维护
安装:
rpm {-i|--install} [install-options] PACKAGE_FILE ...
-v:verbose,显示安装信息
-vv:显示更详细的信息
-h:以#显示程序包安装管理执行进度;每个#表示2%进度
常用组合:
rpm -ivh PACKGE_FILE ...
[install options]
--test #测试安装,但不真正执行安装过程;dry run模式
--nodeps #忽略依赖关系
--replacepkgs #重新安装
--nodigest #不检查包完整性
--nosignature #不检查程序来源的合法性
--noscript #不执行程序中的脚本片段
%pre #安装前的脚本 --nopre
%post #安装后的脚本 --nopost
%preun #卸载前的脚本 --nopreun
%postun #卸载后的脚本 --nopostun
升级:
两种升级方案:
rpm {-U|--upgrade} [install-options] PACKAGE_FILE ...
rpm {-F|--freshen} [install-options] PACKAGE_FILE ...
upgrade:若安装有旧版程序包,则“升级”,如果不存在旧版程序包,则安装;
freshen:若安装有旧版程序包,则“升级”,如果不存在旧版程序包,则不执行任何操作;
常用命令:
rpm -Uvh PACKAGE_FILE ...
rpm -Fvh PACKAGE_FILE ...
[opitons]:
参见安装的options
--oldpackage #降级(用旧版的程序包替换新版的程序包)
--force #强制升级(可能不兼容,使用force无论是否兼容强制升级)
注意:
1、不要对内核做升级操作(Linux3以前升级完成后必须重启系统,升级完成后可能出现系统无法启动的情况);Linux支持多内核版本并存,因此,直接安装新版本内核;
2、如果源程序包的配置文件安装后曾被修改,升级时,新版本提供的同一个配置文件并不会覆盖老版本的配置文件,而是把新版本的配置文件重命名为FILENAME.rpmnew后保留;(若新版本的配置文件与旧版配置文件完全一样,新版配置文件不会安装);
查询:
rpm {-q|--query} [select-options] [query-options]
[select-options]:(查询对象,即查询什么)
-a #查询当前系统上所有已安装的程序包
-f FILE #查询指定文件由哪个程序包安装生成
-g GROUP #查询指定包组的程序包
--whatprovides CAPABLITY #查询指定的CAPABILITY(能力,功能)由哪个包提供
-p,-package /PATH/TO/PACKAGE_FILE #针对尚未安装的程序包做查询操作
[query-options]:(查询的内容)
--changelog #查询rpm包制作changelog(修改日志)
-d、--docfiles #查询程序的文档
-i、--info #程序包的information
-l #列出指定程序包安装完成的所有文件
--scripts #查看程序包自带的脚本片段
-R: #查询指定的程序包所依赖的CAPABILITY
--provides #列出指定程序包所提供的CAPABILITY
常用组合:
rpm -qi PACKAGE
rpm -qf FILE
rpm -qc PACKAGE
rpm -ql PACKAGE
rpm -qd PACKAGE
rpm -qpi PACKEGE_FILE
rpm -qpl PACKAGE_FILE
...
卸载:
rpm {-e|--erase} [--allmatches] [--nodeps] [--noscripts]
[--notriggers] [--test] PACKAGE_NAME ...
校验:
rpm {-V|--verify} [select-options] [verify-options]
校验结果含义:
包的来源合法性及完整性验证:(包安装之前或安装中应该执行的操作)
完整性验证:SHA256
公钥加密(非对称加密):RSA
对称加密:加密,解密使用同一密钥;
非对称加密:密钥是成对的;
public key:公钥,公开给所有人
secret key:私钥,不能公开
制作者制作好程序包后使用单向加密算法计算包的特征码,并将特征码shiyon私钥加密后附加在程序包中。制作者的公钥采用可靠手段发布给所有人(依靠第三方可信机构)
导入所需要的公钥实现校验:(GPG密钥)
rpm --import /PATH/FROM/GPG-PUBLIC-FILE
-K #直接检验程序包来源合法性和包完整性,不用安装
如:CentOS 7发行版光盘提供的密钥文件:RPM-GPG-KEY-CentOS-7
rpm数据库在/var/lib/rpm下(存储状态信息(存储程序包依赖的数据文件))
数据库的重建(数据库损坏时需要做的操作):
rpm {--inittab|--rebuilddb}
--inittab #初始化,如果事先不存在数据库,则新建之;否则,不进行任何操作;
--rebuild #重建,无论当前存在与否,直接重新创建数据库;
为保证程序包的完整性,CentOS 7不允许多个rpm命令同时执行。(包管理器支持事务类操作,每一个操作都是原子,而且每一种操作都有隔离的概念在其中)
使用rpm管理程序包时可能会出现一些问题,如程序包直接的依赖,虽然在安装时可以通过--nodeps来忽略依赖关系,但在使用时可能会出现问题。而手动解决依赖关系又是比较麻烦的一件事情。所以就需要高于rpm,dep等包管理器,能实现在前端自动解决程序包依赖关系并完成安装的工具,解决用户的后顾之忧。
CentOS程序包前端工具:yum,dnf
yum是一个基于C/S架构的工具,yum依赖于rpm而存在
yum获取程序包描述信息至本地缓存中并分析其依赖关系,需要分析本地软件的安装情况,查看依赖的程序哪些已安装,哪些未安装。之后向服务器发送下载的程序包的请求,安装完成后自动删除已安装的程序包(元数据信息不会删除,以便下一次查询。元数据文件可能不止一个,用于存储包名、依赖关系等,其中有一个特殊的文件存放的是每一个文件的校验码信息。每一次客户端请求服务器时,首先请求元数据的校验码信息与本地校验码进行比较,以此检测文件是否发生改变,保证本地文件为最新版本)。
yum不可避免其被取代的命运,因为其本身的工作机制,设计体系以及用到的功能上有一定问题的,比如它的依赖关系虽然能解决,但问题是某一次执行过程当中如果半道终止时,下一次重启将无法解决,因为无法分析上一次包安装成功与否。dnf就是解决yum所遇到的问题的。
YUM:Yellow Update Modifier,有Yellow dog研发
yum repository:简称yum repo,yum仓库
存储了很多rpm包,以及包相关元数据文件(放置于特定目录下:repodata),包的元数据文件可通过createrepo工具创建。
仓库一般是一个文件服务器:
可以基于ftp://提供服务
也可以基于http://提供服务
也可以通过nfs://提供服务
file://(本地的,如本地安装光盘就是一个本地仓库)
配置文件:有两部分组成,/etc/yum.conf中有一个包含指令,可包含其它配置文件,遵循现代将大段的配置文件分成多段的风格
/etc/yum.conf:(主配置文件)为所有yum仓库提供公共配置
/etc/yum.repos.d/*.repo:提供每一个yum仓库的特有配置。用于配置一个或多个仓库指向(一个yum可以同时指定多个不同类仓库,在安装某一程序包时,可同时分析所有仓库,在所有仓库中找一个最新的程序包安装)
仓库指向的定义:
帮助手册:
man yum.conf
[repositoryID] #repositoryid Must be a unique name for each repository, one word.
name=Some name for this repository #name A human readable string describing the repository.
baseurl=url://path/to/repository/ #等号右边不要出现空格,否则容易出现语法错误,baseurl Must be a URL to the directory where
#the yum repository’s ‘repodata’ directory lives. Can be an http://,ftp:// or file:// URL.
#You can specify multiple URLs in one baseurl statement. The best way to do this is like
enable={1|0} #是否启用此仓库(默认为1)
gpgcheck={1|0} #对此仓库的程序包在安装之前是否检查其完整性及来源合法性
repo_check={1|0} #是否检测此仓库的元数据文件的签名信息
gpgchk=URL #此URL指向GPG的密钥文件(有可能是对方仓库提供的,通过URL访问文件)
enablegroups={1|0} #是否允许在次仓库上基于组执行程序包管理,默认为1(支持)
failovermethod={‘roundrobin’(轮询,随机)|‘priority’(优先级,自上而下)} #故障转移方法,baseurl指定多个URL时,当使用的URL损坏时,
#需定义指定下一个URL的策略。默认为roundrobin随机挑选
cost= #开销数字,默认为1000
以CentOS6.5为例定义仓库文件:
yum repolist #列出所有可用仓库
第一次使用yum repolist时yum会到到对应服务器下载数据文件(此处引用了一个不可用的位置,仅用于演示效果,并不是一个真实的repo),下载到本地后列出当前有多少个repo,每个repo的ID是什么以及当前内部有多少个程序包。
yum命令的用法:
yum [options] [command] [package ...]
command is one of:
* install package1 [package2] [...]
* update [package1] [package2] [...]
* update-to [package1] [package2] [...]
* check-update
* upgrade [package1] [package2] [...]
* upgrade-to [package1] [package2] [...]
* distribution-synchronization [package1] [package2] [...]
* remove | erase package1 [package2] [...]
* list [...]
* info [...]
* provides | whatprovides feature1 [feature2] [...]
* clean [ packages | metadata | expire-cache | rpmdb | plugins | all ]
* makecache
* groupinstall group1 [group2] [...]
* groupupdate group1 [group2] [...]
* grouplist [hidden] [groupwildcard] [...]
* groupremove group1 [group2] [...]
* groupinfo group1 [...]
* search string1 [string2] [...]
* shell [filename]
* resolvedep dep1 [dep2] [...]
* localinstall rpmfile1 [rpmfile2] [...]
(maintained for legacy reasons only - use install)
* localupdate rpmfile1 [rpmfile2] [...]
(maintained for legacy reasons only - use update)
* reinstall package1 [package2] [...]
* downgrade package1 [package2] [...]
* deplist package1 [package2] [...]
* repolist [all|enabled|disabled]
* version [ all | installed | available | group-* | nogroups* | grouplist | groupinfo ]
* history [info|list|packages-list|packages-info|summary|addon-info|redo|undo|rollback|new|sync|stats]
* load-transaction [txfile]
* check
* help [command]
原文:https://www.cnblogs.com/long-cnblogs/p/10347143.html