查看portage的手册命令user $
man emerge
一般在gentoo中提及的包都是安装程序,他们的信息一般都在 /usr/portage 目录下
root #
emerge --sync 更新portage的库,
root #
emerge-webrsync 防止防火墙阻拦portage联系镜像库
user $
emerge --search pdf 搜索名称中含有pdf的软件
user $
emerge --searchdesc pdf 描述搜索
root #
emerge --ask app-office/gnumeric 可安装对应的程序
root #
emerge --pretend gnumeric 可以查看安装的程序的依赖
下载一个程序的时候,系统会自动下载一些必要的包并且自动解压缩安装。如果你不想这样做只想解压缩,那么
root #
emerge --fetchonly gnumeric
1、portage的使用
/usr/portage/profiles/use.desc 存放了全局的USE flag说明,/usr/portage/profiles/use.local.desc 存放了本地的USE flag说明。
系统级的profile符号链接到/etc/portage/make.profile。有很多profile,最后输出的结果是他们的并集,最底层的profile在/usr/portage/profiles/base
root #
emerge --info | grep ^USE 查看现在已启用的USE flag /etc/portage/make.conf 存放全局的USE flag,如果取消某个支持,在支持前面加上-
修改/etc/portage/package.use的USE flag可以针对某个单独的程序,它可能是一个文件,也可能是一个文件夹。具体的详情请输入man portage查看。
dev-db/mysql berkdb
root #
USE="-java" emerge seamonkey 可以临时定义取消java支持在seamonkey安装期间。
USE flag定义采用的优先级(从低到高排)
- 默认USE 设置定义在make.defaults 文件 作为你的 profile 的一部分
- 用户自定义 USE 设置 在 /etc/portage/make.conf
- 用户自定义 USE 设置 在 /etc/portage/package.use
- 用户自定义 USE 设置 在环境变量中 (上面例子)
emerge --info 可以查看相关的USE信息
修改USE flag后需要进行如下设置
root #
emerge --update --deep --newuse @world 更新USE flag完成后应该让它在系统中生效
root #
emerge --depclean 移除孤立的包,如果不想包被卸载,使用-p
root #
emerge -p --depclean
root #
revdep-rebuild 重新编译动态链接库 它依赖 app-portage/gentoolkit ,不要忘了先emerge它
root #
emerge --pretend --verbose seamonkey检查包的依赖项 在app-portage/gentoolkit中有专门实现该功能的命令,举例,查询gnumeric包的依赖
root #
emerge --ask app-portage/gentoolkit(安装)
user $
equery --nocolor uses =gnumeric-1.6.3 -a(查询依赖)
还有一种REQUIRED_USE表达式,来表明一组必须或者禁止的支持
REQUIRED_USE="foo? ( bar )" 如果foo被设置了, bar必须被设置 REQUIRED_USE="foo? ( !bar )" 如果foo被设置了, bar必须没被设置. REQUIRED_USE="foo? ( || ( bar baz ) )" 如果foo被设置了, bar 或 baz 必须没被设置. REQUIRED_USE="^^ ( foo bar baz )" foo bar 或 baz恰好有一个必须被设置。 REQUIRED_USE="|| ( foo bar baz )" foo bar 或 baz 至少有一个被设置 REQUIRED_USE="?? ( foo bar baz )" 不超过一个foo bar 或 baz 可能被设置。
2文档
USE flag中添加doc可以支持安装时安装软件的文档。emerge -vp category/package 可查看文档安装情况
文档默认安装在/usr/share/doc/目录下,有可以用app-portage/gentoolkit软件下的equery工具查看 user $
ls -l /usr/share/doc/alsa-lib-1.0.14_rc1
user $
equery files alsa-lib | less
3移除软件
emerge --unmerge 可以移除软件,如果用户修改的配置文件那么配置文件是不会移除的。这是为了再次安装这个软件的时候不需要再次配置。被删除的时候Portage是不会检查是否有软件依赖的,因此需要小心谨慎 root #
emerge --unmerge gnumeric,移除的软件安装的依赖如果需要删除,可使用emerge的
--depclean方法。(上面介绍的)
4更新系统
root #
emerge --update --ask @world 更新系统已安装的应用程序包,它会比较已安装程序的版本号,已安装的程序信息在/var/lib/portage/world中,但是它并没有彻底的更新它们的依赖的包,如果想要更新依赖的包,那么可使用命令
root #
emerge --update --deep @world。但是这仍然不意味着所有的都被更新了,很多包在系统中是在编译和构建的过程中需要的,但是包一旦安装了,这些包就不再需要了。Portage称这些包为build dependencies如果需要这些包也在更新范围内,则使用
root #
emerge --update --deep --with-bdeps=y @world 如果USE被更新了,建议使用
root #
emerge --update --deep --with-bdeps=y --newuse @world Portage会检测或重编译他们。
有的程序安装时会安装一系列的包,如 kde-apps/kde-meta会安装整个完整的KDE环境的依赖包。如果确保没用可以用emerge --unmerge来移除他们。Portage有方法来去除孤立的依赖包,但是由于软件的可用性是依赖于动态来评判的,首先完全的更新整个系统是很重要的。emerge --depclean可实现,执行完成后或许应该重新编译下,防止依赖移除的包。但是现在不需要了,这些功能已经添加到Portage里的。可以用下面的三句命令实现
root #
emerge --update --deep --newuse @world
root #
emerge --depclean
root #
revdep-rebuild
revdep-rebuild 依赖包 app-portage/gentoolkit,不要忘了对它emerge root #
emerge --ask app-portage/gentoolkit
查看包的协议 emerge --search package/category
我们可以配置允许下载的协议在配置文件中
ACCEPT_LICENSE="* -@EULA"
包在安装期间如果需要进行互动(关联)的包含有EULA协议就不会被安装。包如果不含有EULA协议的就可以被安装。也可以指定某个包的交互的包需要的协议 /etc/portage/package.license,例如为包www-client/google-chrome准许google-chrome协议,把下面添加到/etc/portage/package.license:
www-client/google-chrome google-chrome
tips:许可协议在目录 /usr/portage/licenses/下,授权组在目录/usr/portage/profiles/license_groups下,软件许可的第一行大写字母是授权组,后面的每行是单独的许可协议。
授权组定义在ACCEPT_LICENSE 变量中以@符号作为标记,普遍的要求设置只允许安装免费软件和文档。为了达成这个,移除所有的软件协议并只允许免费的组3
ACCEPT_LICENSE="-* @FREE"
4.Blocked packages
[blocks B ] mail-mta/ssmtp (is blocking mail-mta/postfix-2.2.2-r1)
!!! Error: the mail-mta/postfix package conflicts with another package. !!! both can't be installed on the same system together. !!! Please use 'emerge --pretend' to determine blockers.
Ebuilds有两个字段告诉portage它的依赖,一个是 build dependencies,定义在DEPEND 变量中,另一个是run-time dependencies,一般定义在RDEPEND变量中。
解决冲突要么不去安装,要么去删除冲突的包。
5.Masked packages
!!! all ebuilds that could satisfy "bootsplash" have been masked.
!!! possible candidates are: - gnome-base/gnome-2.8.0_pre1 (masked by: ~x86 keyword) - lm-sensors/lm-sensors-2.8.7 (masked by: -sparc keyword) - sys-libs/glibc-2.3.4.20040808 (masked by: -* keyword) - dev-util/cvsd-1.0.2 (masked by: missing keyword) - games-fps/unreal-tournament-451 (masked by: package.mask) - sys-libs/glibc-2.3.2-r11 (masked by: profile) - net-im/skype-2.1.0.81 (masked by: skype-eula license(s))
当用户安装一个gentoo上不是可用的包的时候,就会出现。建议用户等包变为可用的时候再进行安装,下面是各种提示以及错误
Reason for mask | Description |
~arch keyword | The application is not tested sufficiently to be put in the stable branch. Wait a few days or weeks and try again. |
-arch keyword or -* keyword | The application does not work on your architecture. If you believe the package does work file a bug at our Bugzilla website. |
missing keyword | The application has not been tested on your architecture yet. Ask the architecture porting team to test the package or test it for them and report the findings on our Bugzilla website. |
package.mask | The package has been found corrupt, unstable or worse and has been deliberately marked as do-not-use. |
profile | The package has been found not suitable for the current profile. The application might break the system if it is installed or is just not compatible with the profile currently in use. |
license | The package's license is not compatible with the ACCEPT_LICENSE value. Permit its license or the right license group by setting it in/etc/portage/make.conf or in /etc/portage/package.license |
6.必要的USE flag改变
The following USE changes are necessary to proceed: #required by app-text/happypackage-2.0, required by happypackage (argument) >=app-text/feelings-1.0.0 test
如果 --autounmask没有设置,那么错误的信息也可能如下
emerge: there are no ebuilds built with USE flags to satisfy "app-text/feelings[test]". !!! One of the following packages is required to complete your request: - app-text/feelings-1.0.0 (Change USE: +test) (dependency required by "app-text/happypackage-2.0" [ebuild]) (dependency required by "happypackage" [argument])
报警或错误有时候并不一定是依赖的包的问题,也可能是必要的USEflag没有。如上面的例子就是表明,需要设置USE="test",但是系统中并没有设置。为了解决这个问题,在/etc/portage/make.conf中,或者具体到某个包的配置/etc/portage/package.use中,进行设置。
7.Missing dependencies
emerge: there are no ebuilds to satisfy ">=sys-devel/gcc-3.4.2-r4". !!! Problem with ebuild sys-devel/gcc-3.4.2-r2 !!! Possibly a DEPEND/*DEPEND problem.
安装的应用的依赖的包不是可用的时候就会出现。
8.模棱两可的ebuild名字
[ Results for search key : listen ] [ Applications found : 2 ] * dev-tinyos/listen [ Masked ] Latest version available: 1.1.15 Latest version installed: [ Not Installed ] Size of files: 10,032 kB Homepage: http://www.tinyos.net/ Description: Raw listen for TinyOS License: BSD * media-sound/listen [ Masked ] Latest version available: 0.6.3 Latest version installed: [ Not Installed ] Size of files: 859 kB Homepage: http://www.listen-project.org Description: A Music player and management for GNOME License: GPL-2 !!! The short ebuild name "listen" is ambiguous. Please specify !!! one of the above fully-qualified ebuild names instead.
选择的包的名称有多个相似的包,这个时候提供类别名称是个好的选择。
9.循环依赖
!!! Error: circular dependencies: ebuild / net-print/cups-1.1.15-r2 depends on ebuild / app-text/ghostscript-7.05.3-r1 ebuild / app-text/ghostscript-7.05.3-r1 depends on ebuild / net-print/cups-1.1.15-r2
两个包互相依赖~
10.匹配失败
!!! Fetch failed for sys-libs/ncurses-5.4-r5, continuing... (...) !!! Some fetch errors were encountered. Please see above for details.
匹配失败,可能由于ebuild指向不正确或mirror没有同步。
11.系统配置保护
!!! Trying to unmerge package(s) in system profile. 'sys-apps/portage' !!! This could be damaging to your system.
用户删除的包是系统核心组成的一部分。不能被移除。
12摘要验证失败
>>> checking ebuild checksums
!!! Digest verification failed:
软件的签名和gentoo repository里的不匹配。通常,这是由于开发者提交包到tree里的时候犯了错误。通常解决办法就是等一两个小时,tree稳定下来,然后再次尝试。
13 USE flags是什么
USE flags背后的思想是什么?
由于各个环境的不同(生活,办公,开发),所以需要的特性也不同。如果不用openGL,那么为什么软件要加上对他的支持,编译安装的时候需要对它进行支持。它可以帮助用户决定哪些需要和哪些不需要,用户可以选择一个特定的环境以及配置简化流程。
定义一个USE flags
例如,当你USE flags里没有kde的话,那么安装软件时,kde将无法作为一个支持或者一个依赖就行安装,通过正确地定义关键字该系统将专门针对用户的需求定制。
USE flags 存在什么
有两种类型的USE flags:一种是global,一种是local。global全局的可使用USE flags在 main site中,在 /usr/portage/profiles/use.desc中找到。local本地的可使用USE flags在 main site中,可以在/usr/portage/profiles/use.local.desc中找到。
14 使用USE flags
定义USE flags
root #
emerge --info | grep ^USE
USE="-kde -qt4 ldap"
安装或移除相应的USE flags(global)
dev-db/mysql berkdb
增加USE flags berkdb的支持对于mysql而言。(local) 移除用-
定义临时使用的USE flags
有时候我们需要在很短的时间里用到USE flags,这就需要我们设置 /etc/portage/make.conf 文件两次(添加和移除),此命令只在命令行里生效。
下面是仅在seamonkey安装过程中移除对java的支持
root #
USE="-java" emerge seamonkey
优先级
下面最开始的拥有最低的优先级。
-
- 默认的USE设置定义在 make.defaults 文件中,作为你的profile的一部分
- 用户自定义的 USE 设置在 /etc/portage/make.conf
- 用户自定义的 USE 设置在 /etc/portage/package.use
- 用户自定义的 USE 设置 被当做环境变量
为了查看最终的Portage USE设置,执行emerge --info命令,它会列出所有相关的变量(包括USE变量)关于他们当前自定义的Portage相关变量。
新定义的USE flags 让它在整个系统中生效
改变过USE flags之后,整个系统应该更新,以便映射到新的USE flags
root #
emerge --update --deep --newuse @world
然后我们需要移除一些以前过时的依赖
root #
emerge -p --depclean (做这个应该小心,需要确保被移除的依赖在其他的应用中没有使用到)、
然后运行revdep-rebuild 来重新编译那些动态依赖库的程序,它依赖app-portage/gentoolkit,
root #
revdep-rebuild 现在系统已经在使用新的USE flags了
包指定USE flags
让我们以seamonkey为例,来看看它监听了哪些USE flags
root #
emerge --pretend --verbose seamonkey
These are the packages that I would merge, in order: Calculating dependencies ...done! [ebuild R ] www-client/seamonkey-1.0.7 USE="crypt gnome java -debug -ipv6 -ldap -mozcalendar -mozdevelop -moznocompose -moznoirc -moznomail -moznopango -moznoroaming -postgres -xinerama -xprint" 0 kB
app-portage/gentoolkit 有个专门用来实现这个功能的工具
root #
emerge --ask app-portage/gentoolkit
一些包,必须或者禁止某些USE flags,这些都是通过变量REQUIRED_USE表达式来实现的。
Example | Description |
---|---|
REQUIRED_USE="foo? ( bar )" | If foo is set, bar must be set. |
REQUIRED_USE="foo? ( !bar )" | If foo is set, bar must not be set. |
REQUIRED_USE="foo? ( || ( bar baz ) )" | If foo is set, bar or baz must be set. |
REQUIRED_USE="^^ ( foo bar baz )" | Exactly one of foo bar or baz must be set. |
REQUIRED_USE="|| ( foo bar baz )" | At least one of foo bar or baz must be set. |
REQUIRED_USE="?? ( foo bar baz )" | No more than one of foo bar or baz may be set. |
15.Portage 的特性
portage有许多特写让gentoo变得更加的好,许多特性都依赖于某个具体软件去提升它的性能,可靠性和安全性。
启用关闭某个portage特性,编辑/etc/portage/make.conf。更新或设置 FEATURES变量,它已经有了许多特性关键词,被空格分割。在许多场景中,特性依赖的附加工具被安装是很有必要的。
为了有个完整的浏览,请查阅:
user $
man make.conf
为了找出FEATURES的默认设置,运行 emerge --info ,匹配FEATURES
user $
emerge --info | grep ^FEATURES=
16.分布式编译
使用distcc
distcc是通过在服务器上分布式编译的一个项目。它能将源代码分片进行编译。更多的内容可以访问 Distcc
安装distcc
这个工具会自动安装,如果设置成USE=gnome
或 USE=gtk
root #
emerge --ask sys-devel/distcc
激活Portage distcc的支持
再/etc/portage/make.conf中添加distcc到FEATURES 中。然后修改MAKEOPTS 变量,增加系统允许的并行运行任务的数量,一个已知的方案是填充-jN,N是执行cpu运行的数量(包括当前主机)+ 1,但这仅仅是个指导方案。接着运行 distcc-config,输入可用的distcc服务列表,一个简单的例子就是假定可用的DISTCC服务为192.168.1.102(当前主机),192.168.1.103 和192.168.1.104(两个“远程”主机)。
root #
distcc-config --set-hosts "192.168.1.102 192.168.1.103 192.168.1.104"
别忘了运行distcc守护进程
root #
rc-update add distccd default
root #
/etc/init.d/distccd start
17.缓存编译对象
关于ccache
ccache 是一个快速的编译缓存器,无论何时一个项目被编译了,它会缓存编译期间的结果,无论何时相同的项目再次被编译时,编译时间大大减少。第一次ccache运行的时候,它会比正常的编译慢很多,后来重复编译的时候速度会快很多。ccache 对于一个项目需要被重复编译很多次具有帮助性(或同一应用程序的升级是经常发生的),因此对于软件开发人员来讲是很有用的。
注意:ccache会导致大量的编译失败。有时ccache代码保留过期代码对象或损坏的文件,从而导致包无法被emerged,如果发生了(错误如:File not recognized: File truncated出现在build log中),再报告错误之前,请禁用ccache再编译一次 (FEATURES="-ccache" 在
/etc/portage/make.conf)
安装ccache
root #
emerge --ask dev-util/ccache
激活Portage ccache的支持
打开/etc/portage/make.conf,添加ccache
到任意一个FEATURES 变量中,如果不存在就创建,然后添加一个新的变量叫CCACHE_SIZE ,设置成2G。
FEATURES="ccache" CCACHE_SIZE="2G"
我们下面一步要设置缓存目录,
root #
CCACHE_DIR="/var/tmp/ccache" ccache -s 也可以在文件 /etc/portage/make.conf 中设置CCACHE_DIR 变量来改变它
单独运行ccache 的时候,它会使用${HOME}/.ccache/的目录来作为缓存目录,所以我们要像上面做的设置它的CCACHE_DIR
不存在Portage情况下使用ccache
PATH="/usr/lib/ccache/bin:/opt/bin:${PATH}"
18.二进制包支持
创建预构建包
Portage支持安装预构建的包,尽管gentoo本身并不提供预构建的包而且Portage本身可以制作成预构建的包。如果包已经被安装到系统上了,为了创建一个预构建的包,可以使用quickpkg 命令,或者emerge 带上 --buildpkg
或--buildpkgonly
为了拥有portage创建的每个已安装的包的预构建包,在FEATURES 变量中添加buildpkg
。更多的扩展支持为了创建预构建包的设置可以在catalyst中获得。
安装预构建的包
尽管gentoo自身并不提供,但是可以创建一个中央存储库,存储预先构建的包。为了使用这个库,有必要让Portage意识到它,通过修改PORTAGE_BINHOST 变量来指向它。
例如,如果预构建包在 ftp://buildhost/gentoo 中,那么:
PORTAGE_BINHOST="ftp://buildhost/gentoo"
为了安装预构建包,emerge 命令中在--usepkg选项旁边增加--getbinpkg选项,这种格式告诉emerge从上面定义的服务中去下载预构建包,而usepkg告诉emerge获取来源并编译它之前首先试着先下载预构建包。
例如,我们用预构建包安装gnumeric
root #
emerge --usepkg --getbinpkg gnumeric
更多的信息可以查阅 user $
man emerge
分发预先构建的包给别人
如果预构建包需要分发给他人,首先确定这否被允许,这需要检查上游的包。例如,一个包的源在GNU GPL协议下,那么源必须是可用的二进制文件
如果构建的二进制文件是不能被分发的,那么安装程序可以在变量RESTRICT 中定义bindist
,有时这个限制条件在一个或多个USE flags.
默认情况下,因为有这些限制,portage不会隐藏任何包,这可以通过在/etc/portage/make.conf中设置ACCEPT_RESTRICT 变量进行全局的改变。
例如,为了隐藏一个有bindist限制的包,添加下面的行到make.
ACCEPT_RESTRICT="* -bindist"
也可以通过在emerge 命令行中传递--accept-restrict选项重写ACCEPT_RESTRICT变量。例如,--accept-restrict=-bindist可以临时的掩盖有bindist
限制的包。
分发包的时候还得考虑ACCEPT_LICENSE 变量的设置。
19.获取文件
Userfetch
当portage使用的root运行,FEATURES="userfetch"将允许portage获取包源的时候终止root权限,这是一个很小的安全性的改善。
验证Gentoo库快照
Administrators可以选择更新本地的gentoo安装程序tree(使用密码快照验证,链接到gentoo基础服务),这将确保系统下载的包,不会有恶劣的rsync镜子添加到不必要的代码或包。
Gentoo发行媒体OpenPGP钥匙现在可以作为二进制keyring,可通过 app-crypt/gentoo-keys 包安装。GPG是一个加密软件。
root #
emerge --ask app-crypt/gentoo-keys
这个将会将keyring安装到/var/lib/gentoo/gkeys/keyrings/gentoo/release目录
FEATURES="webrsync-gpg" PORTAGE_GPG_DIR="/var/lib/gentoo/gkeys/keyrings/gentoo/release"
[DEFAULT] main-repo = gentoo [gentoo] # Disable synchronization by clearing the values or setting auto-sync = no # Do not set value of the variables in this configuration file using quotes ('' or "")! # For portage-2.2.18 use 'websync' # For portage-2.2.19 and greater use 'webrsync' (websync was renamed to webrsync) sync-type = webrsync sync-uri = auto-sync = yes
确认 app-crypt/gnupg已经被安装(确保USE flags里有latex)
root #
emerge --ask app-crypt/gnupg
使用gpg去验证keys在keyring 中是正确的keys
root #
gpg --homedir /var/lib/gentoo/gkeys/keyrings/gentoo/release --with-fingerprint --list-keys
官方的点击 those listed on the official Gentoo release engineering project page.
root #
gpg --homedir /var/lib/gentoo/gkeys/keyrings/gentoo/release --edit-key 0xDB6B8C1F96D8BF6D trust
gpg命令行变会出现,完全信任key,退出程序通过输入以下:
gpg>
4
gpg>
quit
root #
emerge --sync
root #
emaint sync -a
root #
emaint sync --repo gentoo
root #
emerge-webrsync
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 si::sysinit:/sbin/rc sysinit
这行告诉init,它必须运行/sbin/rc sysinit 去初始化系统,/sbin/rc脚本负责初始化。也许有人会说,init做得并不多,它委托初始化系统的任务到另一个进程中。其次init执行所有符号链接到/etc/runlevels/boot/的脚本,这在下面定义。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 rc::bootwait:/sbin/rc boot
rc脚本执行必要的任务,注意给的boot选项和/etc/runlevels/目录下使用的是相同的名称。
现在,init检查它的配置文件去看看它改运行什么runlevel,它会读取/etc/inittab里的下面一行去决定:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 id:3:initdefault:
在这种情况下(Gentoo的大多数用户将使用),runlevel id 为 3,利用这些信息,init检查必须要运行的runlevel为3的:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 l0:0:wait:/sbin/rc shutdown 2 l1:S1:wait:/sbin/rc single 3 l2:2:wait:/sbin/rc nonetwork 4 l3:3:wait:/sbin/rc default 5 l4:4:wait:/sbin/rc default 6 l5:5:wait:/sbin/rc default 7 l6:6:wait:/sbin/rc reboot
定义级别3的那行,使用 rc脚本去开始运行服务,后面的参数也跟 /etc/runlevels/的子文件夹同名。
当rc运行结束,init决定应该激活的虚拟控制台和在每个控制台需要运行什么命令:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 c1:12345:respawn:/sbin/agetty 38400 tty1 linux 2 c2:12345:respawn:/sbin/agetty 38400 tty2 linux 3 c3:12345:respawn:/sbin/agetty 38400 tty3 linux 4 c4:12345:respawn:/sbin/agetty 38400 tty4 linux 5 c5:12345:respawn:/sbin/agetty 38400 tty5 linux 6 c6:12345:respawn:/sbin/agetty 38400 tty6 linux
可用的runlevels
runlevel是系统运行的状态,包含一组脚本(runlevel或initscripts)进入或离开时,必须执行一个runlevel。
Gentoo中,有七个runlevels:三个内部runlevels,4个用户定义的runlevels。
内部的runlevels为sysinit,shutdown和reboot,执行着他们名称的含义,初始化系统,供电系统和重新启动系统。
用户自定义的runlevels在/etc/runlevels/文件夹下。分别为boot, default, nonetwork 和 single 。boot的runlevel 执行了其他runleves也使用的所有系统必备的服务。剩下的三个runlevels开始的服务是不同的,default用于日常的操作,nonetwork使用时不需要网络连接,single 系统需要被修复的时候使用。
使用initscripts
rc一开始处理的脚本叫做init scripts ,/etc/init.d/里的每个脚本都能带start
, stop
, restart
, zap
, status
, ineed
, iuse
,needsme
, usesme
, 或 broken参数执行。
开始、停止或重新启动一个服务(和所有依赖的服务),start
, stop
, 和 restart
参数应该被带上:
root #
/etc/init.d/postfix start
注意:如有A服务依赖此停止的服务B(但是对于A来说,B不是必须的,而仅仅是使用到的)则不会影响A的运行
停止一个服务,但不停止依赖它的服务,可以加上--nodeps参数
root #
/etc/init.d/postfix --nodeps stop
下面可查询服务的状态
root #
/etc/init.d/postfix status
如果显示的状态和实际的运行状态不符,下面命令可以更新状态
root #
/etc/init.d/postfix zap
如果要查看服务的依赖,使用iuse或者ineed,ineed可以看到服务的正确运行所必需的服务,
iuse可以查看该服务使用的服务,但他们对于确保正确运行来说不是必要的。
root #
/etc/init.d/postfix ineed
同样的,它也可以根据该服务去查找什么服务依赖于自己,needsme(确保运行必须的)usesme(使用到的,但不是必须的)
root #
/etc/init.d/postfix needsme
最后,可以查看该服务没有安装但是需要依赖的服务
root #
/etc/init.d/postfix broken
更新runlevels
rc-update
Gentoo的init系统使用依赖列表去决定什么服务优先启动,这是一项枯燥的工作,gentoo官方不希望我们手动去做,他们创建了一个工具去减少runlevels和init脚本的管理。
使用rc-update可以congrunlevel中增加或移除init脚本, rc-update工具也会自动的通知depscan.sh去重编译依赖列表。
增加或移除服务
在先前的指令里,init脚本已经被添加到 default runlevel里了。 rc-update需要添加参数add
, del
, 或 show。如:
root #
rc-update del postfix default
rc-update -v show命令显示所有可用的init scripts,列出他们的运行级别
root #
rc-update -v show 也可以 rc-update show仅仅显示可用的init scripts和他们的运行级别
配置服务
为什么需要额外的配置
Init脚本可能相当复杂,因此不需要用户直接编辑init脚本,因为这将使它更容易出错.然而重要的是能够配置这样的服务。例如,用户可能想给服务本身更多的选项。
还有个原因是用户可以撤销它的配置,风险小
conf.d目录
Gentoo提供一个简单的方法去配置这样一个服务:每个可以配置的脚本都有/etc/conf.d/这样一个脚本。例如,apache2 initscript (叫做/etc/init.d/apache2)有个配置文件叫做/etc/conf.d/apache2.Apache 2服务启动时,它可以包含选项给Apache 2服务:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
APACHE2_OPTS="-D PHP5"
这样一个文件里只包含变量,使它很容易配置服务。
编写启动脚本(initscripts)
这真的必要吗
不,编写一个init脚本通常是没有必要,Gentoo提供现成的init脚本。然而,一些用户可能不使用Portage安装服务,在这种情况下,他们将最有可能需要创建一个init脚本。
如果服务不是明确的显示为gentoo而写的,请不要使用此服务提供的init script,gentoo的init script跟其他的linux分支不兼容,除非服务使用了 OpenRC!
布局
一个init脚本的基本布局如下所示
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#!/sbin/openrc-run
depend() {
(Dependency information)
}
start() {
(Commands necessary to start the service)
}
stop() {
(Commands necessary to stop the service)
}
每个init script都需要使用start()方法去定义,其他部分都是可选。
依赖
有两个dependency-alike设置可以影响init scripts的启动与排序:use和need。还有两个影响顺序的方法叫做before和after。最后两个没有依赖--如果选择的服务没有计划执行(或失败),他们不会使原始的init script执行失败。
1、use设置通知init system,脚本使用的方法由被选择的脚本提供,但是并不直接依赖与它。一个好的示例应该使用use logger或 use dns。如果这些服务是可用的,他们会很好的使用。但是如果服务没有logger或dns服务,服务仍然会工作,但是如果服务存在,他们会在开始前执行并使用它。
2、need设置依赖比较强,该服务启动之前需要另一个服务启动成功。如果另一个服务重启了,该服务也会重启。
3、当使用before,如果指定的脚本时init level的一部分的时候,给定的脚本会在指定的脚本之前运行
4、after跟上面类似,不过是之后运行。
一个virtual dependency是由一个服务提供的依赖,但不仅仅是由一个服务提供,一个init script可以依赖一个system logger,但是由很多system logger是可用的(metalogd, syslog-ng, sysklogd, ..),不可能need他们所有,所以我们只依赖一个virtual dependency
比如:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
depend() {
need net
use logger dns
provide mta
}
可以看到:
需要net(virtual)依赖(哪种提供具体的依赖,比如:/etc/init.d/net.eth0)
使用logger(virtual)依赖(哪种提供具体的依赖,比如:/etc/init.d/syslog-ng)
使用dns (virtual)依赖(哪种提供具体的依赖,比如:/etc/init.d/named)
提供mta (virtual)依赖(这是常见的所有邮件服务器)
控制顺序
可以控制init system脚本的顺序,由dependency 设置的use 和need进行决定,也通过 before 和 after设置顺序,下面是portmap 的示例:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
depend() {
need net
before inetd
before xinetd
}
也可以用*来捕获到同一个runlevel里的所有服务,尽管这是不可取的。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
depend() { before * }
如果服务必须写入本地磁盘,它应该需要localmount。如果把所有的东西放到/var/run/里当成一个pidfile,之后它会在bootmisc之后开始
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
depend() {
need localmount
after bootmisc
}
标准函数
在depend()函数旁,也很有必要定义start()函数,它包含了所有初始化服务的必要命令,使用
ebegin和
eend去告诉用户发生了什么是一个很明智的做法。、
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
start() { if [ "${RC_CMD}" = "restart" ]; then # Do something in case a restart requires more than stop, start fi ebegin "Starting my_service" start-stop-daemon --start --exec /path/to/my_service \ --pidfile /path/to/my_pidfile eend $? }
--exec和--pidfile两个都应该使用在start和stop函数中,如果一个服务不创建pidfile,如果可能的话就使用--make-pidfile。也可以添加--quiet作为start-stop-daemon的参数,但是这是不被推荐的,除非该服务很冗长。如果服务失败开始调试使用--quiet可能会阻碍它的进行。
在上面的例子中使用的另一个显著的设置是检查RC_CMD变量的内容,不像上面的init script 系统,新的openrc系统不支持指定脚本的重启功能。相应的,脚本需要检查RC_CMD 变量的内容,去检查方法(start()
或 stop()
)否作为restart的一部分。
note:确保--exec实际调用一个服务,而不仅仅是一个shell脚本,这就是init script 应该做的。
更多的示例可以参考/etc/init.d/
另外一个可以定义的(非必须)是stop(),如果start-stop-daemon正在使用,init system足够的智能的填充这个函数。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
stop() { ebegin "Stopping my_service" start-stop-daemon --stop --exec /path/to/my_service \ --pidfile /path/to/my_pidfile eend $? }
如果该服务运行其他的脚本(如bash,python或perl),然后这个脚本之后更改了它的名称(如原来是foo.py改成了foo),所以添加--name到start-stop-daemon中便很有必要了。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
start() { ebegin "Starting my_script" start-stop-daemon --start --exec /path/to/my_script \ --pidfile /path/to/my_pidfile --name foo eend $? }
如果想要查阅更多,start-stop-daemon 有一个优秀的可用的man page可供查询。
user $
man start-stop-daemon
Gentoo的init script的语法以POSIX Shell 为基础,由此用户可以免费的在他们的init scripts里使用sh-compatible的设计。确保其他的设计,如bash-specific,在 init scripts之外去确保这些脚本能够正常的在gentoo的init scripts执行。
添加自定义选项
如果initscript需要支持比我们已经遇到的更多的选择,就增加参数到extra_commands 变量中,然后创建跟此选项一样名称的函数,例如,支持restartdelay函数:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
extra_commands="restartdelay" restartdelay() { stop sleep 3 # Wait 3 seconds before starting again start }
restart()不能被覆盖
服务配置变量
为了支持/etc/conf.d/的配置文件,没有具体需要实现:当init脚本执行,以下文件是自动的.
/etc/conf.d/YOUR_INIT_SCRIPT
/etc/conf.d/basic
/etc/rc.conf
同样,如果init脚本提供了一个虚拟的依赖(如网络),与该文件依赖的关联(如/etc/conf.d/net)将被使用。
改变runlevel 的行为
谁可能从中受益
许多笔记本电脑用户知道的情况:在家,他们需要使用net.eth0,在路上的时候他们不想要使用net.eth0(因为没有可用的network),Gentoo的runlevel 的行为可以随便改变这些。
例如:第二个“default”runlevel 可以被创建,这些是在引导的的时候分配给它的其他的init script。在引导的时候,用户可以选择什么样的default runlevel需要被使用。
使用softlevel
首先,先要创建第二个“默认”的runlevel,下面是我们创建的一个offline的runlevel
root #
mkdir /etc/runlevels/offline
为新建的offline的runlevel创建相应的init scripts,例如,有一个复制当前的default runlevel但是没有net.eth0:
1 root #cd /etc/runlevels/default 2 root #for service in *; do rc-update add $service offline; done 3 root #rc-update del net.eth0 offline 4 root #rc-update show offline 5 (Partial sample Output) 6 acpid | offline 7 domainname | offline 8 local | offline 9 net.eth0 |
即使 net.eth0从offline的runlevel里移除了,udev可能想尝试启动任何设备检测并会运行适当的服务,有一个功能叫做hotplugging,默认情况下,gentoo不会启用hotplugging。
为了启用hotplugging,但只有一组选定的脚本启用,在/etc/rc.conf里使用 rc_hotplug 变量。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
rc_hotplug="net.wlan !net.*"
设备启动服务的更多信息,请查阅/etc/rc.conf
编辑bootloader配置,为offline增加一个新的入口,在这个入口中,增加softlevel=offline
作为boot的参数。
使用bootlevel
使用bootlevel 完全类似于softlevel,他们的区别仅仅是定义的第二个“boot”runlevel代替了第二个“default”runlevel。
环境变量
介绍
一个环境变量是一个命名的包含由一个或多个应用程序使用的信息对象,许多用户(特别是新接触linux的)觉得这有点奇怪或难以管理,不管如何,通过使用环境变量可以很容易地更改一个或多个程序的配置这是一个错误的观念。
重要的例子
下面是linux系统的一系列的变量,也解释了他们的用处:
Variable | Description |
PATH | This variable contains a colon-separated list of directories in which the system looks for executable files. If a name is entered of an executable (such as ls, rc-update, or emerge) but this executable is not located in a listed directory, then the system will not execute it (unless the full path is entered as the command, such as /bin/ls). |
ROOTPATH | This variable has the same function as PATH, but this one only lists the directories that should be checked when the root-user enters a command. |
LDPATH | This variable contains a colon-separated list of directories in which the dynamical linker searches through to find a library. |
MANPATH | This variable contains a colon-separated list of directories in which the man command searches for the man pages. |
INFODIR | This variable contains a colon-separated list of directories in which the info command searches for the info pages. |
PAGER | This variable contains the path to the program used to list the contents of files through (such as less or more). |
EDITOR | This variable contains the path to the program used to change the contents of files with (such as nano or vi). |
KDEDIRS | This variable contains a colon-separated list of directories which contain KDE-specific material. |
CONFIG_PROTECT | This variable contains a space-delimited list of directories which should be protected by Portage during updates. |
CONFIG_PROTECT_MASK | This variable contains a space-delimited list of directories which should not be protected by Portage during updates. |
下面是例子中所有这些变量的定义:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
PATH="/bin:/usr/bin:/usr/local/bin:/opt/bin:/usr/games/bin" ROOTPATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin" LDPATH="/lib:/usr/lib:/usr/local/lib:/usr/lib/gcc-lib/i686-pc-linux-gnu/3.2.3" MANPATH="/usr/share/man:/usr/local/share/man" INFODIR="/usr/share/info:/usr/local/share/info" PAGER="/usr/bin/less" EDITOR="/usr/bin/vim" KDEDIRS="/usr" CONFIG_PROTECT="/usr/X11R6/lib/X11/xkb /opt/tomcat/conf \ /usr/kde/3.1/share/config /usr/share/texmf/tex/generic/config/ \ /usr/share/texmf/tex/platex/config/ /usr/share/config" CONFIG_PROTECT_MASK="/etc/gconf"
定义全局变量
env.d目录
Gentoo介绍了/etc/env.d/目录,为了集中的定义这些变量 。在这个文件夹中,大量的文件是可用的,如00basic,05gcc等。这些都是上面提到的名字的应用程序所需要的。
例如,当gcc 被安装了,05gcc 文件被ebuild 创建,它包含了以下定义的变量:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
PATH="/usr/i686-pc-linux-gnu/gcc-bin/3.2" ROOTPATH="/usr/i686-pc-linux-gnu/gcc-bin/3.2" MANPATH="/usr/share/gcc-data/i686-pc-linux-gnu/3.2/man" INFOPATH="/usr/share/gcc-data/i686-pc-linux-gnu/3.2/info" CC="gcc" CXX="g++" LDPATH="/usr/lib/gcc-lib/i686-pc-linux-gnu/3.2.3"
其他发行版可能会告诉他们的用户更改或添加环境变量定义在/etc/profile或其他目录中,Gentoo另一方面方便了用户(也方便了portage)去维护管理环境变量,不用去注意众多的包含环境变量的文件。
例如:当gcc 被更新完毕,/etc/env.d/05gcc文件也会被更新,不需要请求任何用户交互。
这不仅有利于Portage,也有利于用户,有时用户可能被要求设置一个环境变量的系统。例如我们使用http_proxy变量。作为代替了混乱的/etc/profile,用户只需要添加一个文件(如/etc/env.d/99local),然后进去定义他:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
http_proxy="proxy.server.com:8080"
通过使用相同的文件,定义所有关于自身管理的变量,用户可以快速阅览他们定义的变量。
env-update
许多在 /etc/env.d/里的文件都定义了PATH 变量,这不是一个错误:当 env-update命令执行的时候,在更新环境变量之前,它会添加一些定义的变量。从而方便包(或用户)来添加自己的环境变量设置,而不会干扰现有值。
env-update脚本将会按照这些文件(/etc/env.d/ 里的)的字母顺序增加这些变量,这些文件名必须以两个数字开头。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
00basic 99kde-env 99local +-------------+----------------+-------------+ PATH="/bin:/usr/bin:/usr/kde/3.2/bin:/usr/local/bin"
变量的重复并不总是发生,除了这几个变量:ADA_INCLUDE_PATH, ADA_OBJECTS_PATH, CLASSPATH, KDEDIRS, PATH, LDPATH, MANPATH,INFODIR, INFOPATH, ROOTPATH, CONFIG_PROTECT, CONFIG_PROTECT_MASK, PRELINK_PATH, PRELINK_PATH_MASK, PKG_CONFIG_PATH, 和PYTHONPATH。对于其他的变量,最后定义的变量是有效的(文件顺序)。
如果可能的话,通过添加COLON_SEPARATED 或SPACE_SEPARATED 的变量名,添加更多的变量到concatenate-variables 列表中(也定义在/etc/env.d/文件中)。
当执行env-update命令,该脚本会创建所有的环境变量,并把他们放在/etc/profile.env(由 /etc/profile所使用的)。它还会从LDPATH 变量中提取信息然后使用这些信息创建 /etc/ld.so.conf。在这之后,它会运行ldconfig 去再次创建动态链接器(dynamical linker)使用的/etc/ld.so.cache文件。
为了运行env-update后立刻有影响,运行下面的命令去更新环境。自己安装gentoo的用户可能从安装指令中记得:
root #
env-update && source /etc/profile
上面的命令只在当前的终端、新的终端,他们的子终端进行更新。因此如果用户工作在X11,他需要在每个新打开的终端输入source /etc/profile或者重启X,这样所有终端就可以引用新的变量了。如果使用的是登录管理器,那么必须成为root用户并且重启 /etc/init.d/xdm服务。
note:当定义了其他变量的时候,不会用 shell变量。这意味着像FOO="$BAR"的($BAR是其他变量)的东西是被禁止的。
定义局部变量
用户指定
它可能没有必要定义一个全局环境变量,比如,一个可能需要增加/home/my_user/bin和当前的工作目录(用户所在的目录)添加到PATH 变量,但是不想其他用户拥有此PATH变量。为了定义一个本地的变量,使用~/.bashrc或~/.bash_profile:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
# A colon followed by no directory is treated as the current working directory PATH="${PATH}:/home/my_user/bin:"
在登录/登出后,PATH变量会被更新。
指定会话
有时严格的定义是需要的。比如,一个用户可能需要有权限从一个临时的目录中去使用二进制创建而不使用path或想要去短时间内编辑~/.bashrc 。
在这样的例子里,在当前会话中使用export 命令定义PATH变量,只要用户不退出会话,该PATH变量就会一直被临时的使用。
root #
export PATH="${PATH}:/home/my_user/tmp/usr/bin"